1use super::functions::*;
6use oxilean_kernel::{BinderInfo, Expr, FVarId, Level, Name};
7use std::collections::HashMap;
8
9use super::metacontext_type::MetaContext;
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
13pub struct MVarId(pub u64);
14impl MVarId {
15 pub fn new(id: u64) -> Self {
17 MVarId(id)
18 }
19}
20#[derive(Clone, Debug)]
22pub struct MetavarDecl {
23 pub ty: Expr,
25 pub lctx_snapshot: Vec<FVarId>,
27 pub kind: MetavarKind,
29 pub user_name: Name,
31 pub num_scope_args: u32,
33 pub depth: u32,
35}
36#[allow(dead_code)]
38pub struct MetaBasicWindow {
39 pub buffer: std::collections::VecDeque<f64>,
40 pub capacity: usize,
41 pub running_sum: f64,
42}
43#[allow(dead_code)]
44impl MetaBasicWindow {
45 pub fn new(capacity: usize) -> Self {
46 MetaBasicWindow {
47 buffer: std::collections::VecDeque::new(),
48 capacity,
49 running_sum: 0.0,
50 }
51 }
52 pub fn push(&mut self, v: f64) {
53 if self.buffer.len() >= self.capacity {
54 if let Some(old) = self.buffer.pop_front() {
55 self.running_sum -= old;
56 }
57 }
58 self.buffer.push_back(v);
59 self.running_sum += v;
60 }
61 pub fn mean(&self) -> f64 {
62 if self.buffer.is_empty() {
63 0.0
64 } else {
65 self.running_sum / self.buffer.len() as f64
66 }
67 }
68 pub fn variance(&self) -> f64 {
69 if self.buffer.len() < 2 {
70 return 0.0;
71 }
72 let m = self.mean();
73 self.buffer.iter().map(|&x| (x - m).powi(2)).sum::<f64>() / self.buffer.len() as f64
74 }
75 pub fn std_dev(&self) -> f64 {
76 self.variance().sqrt()
77 }
78 pub fn len(&self) -> usize {
79 self.buffer.len()
80 }
81 pub fn is_full(&self) -> bool {
82 self.buffer.len() >= self.capacity
83 }
84 pub fn is_empty(&self) -> bool {
85 self.buffer.is_empty()
86 }
87}
88#[derive(Clone, Debug, Default)]
90pub struct UnificationTrace {
91 pub(super) entries: Vec<UnificationEntry>,
92 pub(super) enabled: bool,
93}
94impl UnificationTrace {
95 pub fn new() -> Self {
97 Self {
98 entries: Vec::new(),
99 enabled: true,
100 }
101 }
102 pub fn disabled() -> Self {
104 Self {
105 entries: Vec::new(),
106 enabled: false,
107 }
108 }
109 pub fn record(&mut self, lhs: &str, rhs: &str, success: bool, depth: u32) {
111 if self.enabled {
112 self.entries.push(UnificationEntry {
113 lhs: lhs.to_string(),
114 rhs: rhs.to_string(),
115 success,
116 depth,
117 });
118 }
119 }
120 pub fn len(&self) -> usize {
122 self.entries.len()
123 }
124 pub fn is_empty(&self) -> bool {
126 self.entries.is_empty()
127 }
128 pub fn success_count(&self) -> usize {
130 self.entries.iter().filter(|e| e.success).count()
131 }
132 pub fn failure_count(&self) -> usize {
134 self.entries.iter().filter(|e| !e.success).count()
135 }
136 pub fn clear(&mut self) {
138 self.entries.clear();
139 }
140 pub fn set_enabled(&mut self, enabled: bool) {
142 self.enabled = enabled;
143 }
144 pub fn is_enabled(&self) -> bool {
146 self.enabled
147 }
148}
149#[allow(dead_code)]
151pub struct BasicConfig {
152 pub values: std::collections::HashMap<String, BasicConfigValue>,
153 pub read_only: bool,
154}
155#[allow(dead_code)]
156impl BasicConfig {
157 pub fn new() -> Self {
158 BasicConfig {
159 values: std::collections::HashMap::new(),
160 read_only: false,
161 }
162 }
163 pub fn set(&mut self, key: &str, value: BasicConfigValue) -> bool {
164 if self.read_only {
165 return false;
166 }
167 self.values.insert(key.to_string(), value);
168 true
169 }
170 pub fn get(&self, key: &str) -> Option<&BasicConfigValue> {
171 self.values.get(key)
172 }
173 pub fn get_bool(&self, key: &str) -> Option<bool> {
174 self.get(key)?.as_bool()
175 }
176 pub fn get_int(&self, key: &str) -> Option<i64> {
177 self.get(key)?.as_int()
178 }
179 pub fn get_str(&self, key: &str) -> Option<&str> {
180 self.get(key)?.as_str()
181 }
182 pub fn set_bool(&mut self, key: &str, v: bool) -> bool {
183 self.set(key, BasicConfigValue::Bool(v))
184 }
185 pub fn set_int(&mut self, key: &str, v: i64) -> bool {
186 self.set(key, BasicConfigValue::Int(v))
187 }
188 pub fn set_str(&mut self, key: &str, v: &str) -> bool {
189 self.set(key, BasicConfigValue::Str(v.to_string()))
190 }
191 pub fn lock(&mut self) {
192 self.read_only = true;
193 }
194 pub fn unlock(&mut self) {
195 self.read_only = false;
196 }
197 pub fn size(&self) -> usize {
198 self.values.len()
199 }
200 pub fn has(&self, key: &str) -> bool {
201 self.values.contains_key(key)
202 }
203 pub fn remove(&mut self, key: &str) -> bool {
204 self.values.remove(key).is_some()
205 }
206}
207#[derive(Clone, Debug, Default)]
209pub struct MetaStatistics {
210 pub total_created: usize,
212 pub total_assigned: usize,
214 pub total_pending: usize,
216 pub total_locals: usize,
218 pub total_postponed: usize,
220}
221impl MetaStatistics {
222 pub fn from_ctx(ctx: &MetaContext) -> Self {
224 let total_created = ctx.mvar_count();
225 let pending = ctx.unassigned_mvars();
226 let total_assigned = total_created - pending.len();
227 Self {
228 total_created,
229 total_assigned,
230 total_pending: pending.len(),
231 total_locals: ctx.num_locals(),
232 total_postponed: ctx.num_postponed(),
233 }
234 }
235 pub fn all_resolved(&self) -> bool {
237 self.total_pending == 0
238 }
239 pub fn summary(&self) -> String {
241 format!(
242 "MetaStatistics {{ created={}, assigned={}, pending={}, locals={}, postponed={} }}",
243 self.total_created,
244 self.total_assigned,
245 self.total_pending,
246 self.total_locals,
247 self.total_postponed,
248 )
249 }
250}
251#[allow(dead_code)]
253pub struct MetaBasicExtMap<V> {
254 pub data: std::collections::HashMap<String, V>,
255 pub default_key: Option<String>,
256}
257#[allow(dead_code)]
258impl<V: Clone + Default> MetaBasicExtMap<V> {
259 pub fn new() -> Self {
260 MetaBasicExtMap {
261 data: std::collections::HashMap::new(),
262 default_key: None,
263 }
264 }
265 pub fn insert(&mut self, key: &str, value: V) {
266 self.data.insert(key.to_string(), value);
267 }
268 pub fn get(&self, key: &str) -> Option<&V> {
269 self.data.get(key)
270 }
271 pub fn get_or_default(&self, key: &str) -> V {
272 self.data.get(key).cloned().unwrap_or_default()
273 }
274 pub fn contains(&self, key: &str) -> bool {
275 self.data.contains_key(key)
276 }
277 pub fn remove(&mut self, key: &str) -> Option<V> {
278 self.data.remove(key)
279 }
280 pub fn size(&self) -> usize {
281 self.data.len()
282 }
283 pub fn is_empty(&self) -> bool {
284 self.data.is_empty()
285 }
286 pub fn set_default(&mut self, key: &str) {
287 self.default_key = Some(key.to_string());
288 }
289 pub fn keys_sorted(&self) -> Vec<&String> {
290 let mut keys: Vec<&String> = self.data.keys().collect();
291 keys.sort();
292 keys
293 }
294}
295#[allow(dead_code)]
297#[derive(Debug, Clone, Default)]
298pub struct MetaBasicExt {
299 pub tag: u32,
301 pub description: Option<String>,
303}
304#[allow(dead_code)]
305impl MetaBasicExt {
306 pub fn new() -> Self {
308 Self {
309 tag: 0,
310 description: None,
311 }
312 }
313 pub fn with_tag(mut self, tag: u32) -> Self {
315 self.tag = tag;
316 self
317 }
318 pub fn with_description(mut self, desc: impl Into<String>) -> Self {
320 self.description = Some(desc.into());
321 self
322 }
323 pub fn has_description(&self) -> bool {
325 self.description.is_some()
326 }
327}
328#[derive(Clone, Copy, Debug, PartialEq, Eq)]
330pub enum MetavarKind {
331 Natural,
333 Synthetic,
335 SyntheticOpaque,
337}
338#[allow(dead_code)]
339pub struct BasicExtDiff3800 {
340 pub added: Vec<String>,
341 pub removed: Vec<String>,
342 pub unchanged: Vec<String>,
343}
344impl BasicExtDiff3800 {
345 #[allow(dead_code)]
346 pub fn new() -> Self {
347 Self {
348 added: Vec::new(),
349 removed: Vec::new(),
350 unchanged: Vec::new(),
351 }
352 }
353 #[allow(dead_code)]
354 pub fn add(&mut self, s: &str) {
355 self.added.push(s.to_string());
356 }
357 #[allow(dead_code)]
358 pub fn remove(&mut self, s: &str) {
359 self.removed.push(s.to_string());
360 }
361 #[allow(dead_code)]
362 pub fn keep(&mut self, s: &str) {
363 self.unchanged.push(s.to_string());
364 }
365 #[allow(dead_code)]
366 pub fn is_empty(&self) -> bool {
367 self.added.is_empty() && self.removed.is_empty()
368 }
369 #[allow(dead_code)]
370 pub fn total_changes(&self) -> usize {
371 self.added.len() + self.removed.len()
372 }
373 #[allow(dead_code)]
374 pub fn net_additions(&self) -> i64 {
375 self.added.len() as i64 - self.removed.len() as i64
376 }
377 #[allow(dead_code)]
378 pub fn summary(&self) -> String {
379 format!(
380 "+{} -{} =={}",
381 self.added.len(),
382 self.removed.len(),
383 self.unchanged.len()
384 )
385 }
386}
387#[allow(dead_code)]
389pub struct BasicDiagnostics {
390 pub errors: Vec<String>,
391 pub warnings: Vec<String>,
392 pub notes: Vec<String>,
393 pub max_errors: usize,
394}
395#[allow(dead_code)]
396impl BasicDiagnostics {
397 pub fn new(max_errors: usize) -> Self {
398 BasicDiagnostics {
399 errors: Vec::new(),
400 warnings: Vec::new(),
401 notes: Vec::new(),
402 max_errors,
403 }
404 }
405 pub fn error(&mut self, msg: &str) {
406 if self.errors.len() < self.max_errors {
407 self.errors.push(msg.to_string());
408 }
409 }
410 pub fn warning(&mut self, msg: &str) {
411 self.warnings.push(msg.to_string());
412 }
413 pub fn note(&mut self, msg: &str) {
414 self.notes.push(msg.to_string());
415 }
416 pub fn has_errors(&self) -> bool {
417 !self.errors.is_empty()
418 }
419 pub fn num_errors(&self) -> usize {
420 self.errors.len()
421 }
422 pub fn num_warnings(&self) -> usize {
423 self.warnings.len()
424 }
425 pub fn is_clean(&self) -> bool {
426 self.errors.is_empty() && self.warnings.is_empty()
427 }
428 pub fn at_error_limit(&self) -> bool {
429 self.errors.len() >= self.max_errors
430 }
431 pub fn clear(&mut self) {
432 self.errors.clear();
433 self.warnings.clear();
434 self.notes.clear();
435 }
436 pub fn summary(&self) -> String {
437 format!(
438 "{} error(s), {} warning(s)",
439 self.errors.len(),
440 self.warnings.len()
441 )
442 }
443}
444pub struct MetaBasicExtUtil {
445 pub key: String,
446 pub data: Vec<i64>,
447 pub active: bool,
448 pub flags: u32,
449}
450#[allow(dead_code)]
451impl MetaBasicExtUtil {
452 pub fn new(key: &str) -> Self {
453 MetaBasicExtUtil {
454 key: key.to_string(),
455 data: Vec::new(),
456 active: true,
457 flags: 0,
458 }
459 }
460 pub fn push(&mut self, v: i64) {
461 self.data.push(v);
462 }
463 pub fn pop(&mut self) -> Option<i64> {
464 self.data.pop()
465 }
466 pub fn sum(&self) -> i64 {
467 self.data.iter().sum()
468 }
469 pub fn min_val(&self) -> Option<i64> {
470 self.data.iter().copied().reduce(i64::min)
471 }
472 pub fn max_val(&self) -> Option<i64> {
473 self.data.iter().copied().reduce(i64::max)
474 }
475 pub fn len(&self) -> usize {
476 self.data.len()
477 }
478 pub fn is_empty(&self) -> bool {
479 self.data.is_empty()
480 }
481 pub fn clear(&mut self) {
482 self.data.clear();
483 }
484 pub fn set_flag(&mut self, bit: u32) {
485 self.flags |= 1 << bit;
486 }
487 pub fn has_flag(&self, bit: u32) -> bool {
488 self.flags & (1 << bit) != 0
489 }
490 pub fn deactivate(&mut self) {
491 self.active = false;
492 }
493 pub fn activate(&mut self) {
494 self.active = true;
495 }
496}
497#[allow(dead_code)]
499#[derive(Debug, Clone, Default)]
500pub struct MetaBasicExt2 {
501 pub tag: u32,
503}
504#[allow(dead_code)]
505impl MetaBasicExt2 {
506 pub fn new() -> Self {
508 Self { tag: 0 }
509 }
510}
511#[allow(dead_code)]
513pub struct MetaBasicStateMachine {
514 pub state: MetaBasicState,
515 pub transitions: usize,
516 pub history: Vec<String>,
517}
518#[allow(dead_code)]
519impl MetaBasicStateMachine {
520 pub fn new() -> Self {
521 MetaBasicStateMachine {
522 state: MetaBasicState::Initial,
523 transitions: 0,
524 history: Vec::new(),
525 }
526 }
527 pub fn transition_to(&mut self, new_state: MetaBasicState) -> bool {
528 if self.state.is_terminal() {
529 return false;
530 }
531 let desc = format!("{:?} -> {:?}", self.state, new_state);
532 self.state = new_state;
533 self.transitions += 1;
534 self.history.push(desc);
535 true
536 }
537 pub fn start(&mut self) -> bool {
538 self.transition_to(MetaBasicState::Running)
539 }
540 pub fn pause(&mut self) -> bool {
541 self.transition_to(MetaBasicState::Paused)
542 }
543 pub fn complete(&mut self) -> bool {
544 self.transition_to(MetaBasicState::Complete)
545 }
546 pub fn fail(&mut self, msg: &str) -> bool {
547 self.transition_to(MetaBasicState::Failed(msg.to_string()))
548 }
549 pub fn num_transitions(&self) -> usize {
550 self.transitions
551 }
552}
553#[allow(dead_code)]
555#[derive(Debug, Clone, PartialEq)]
556pub enum BasicResult {
557 Ok(String),
558 Err(String),
559 Partial { done: usize, total: usize },
560 Skipped,
561}
562#[allow(dead_code)]
563impl BasicResult {
564 pub fn is_ok(&self) -> bool {
565 matches!(self, BasicResult::Ok(_))
566 }
567 pub fn is_err(&self) -> bool {
568 matches!(self, BasicResult::Err(_))
569 }
570 pub fn is_partial(&self) -> bool {
571 matches!(self, BasicResult::Partial { .. })
572 }
573 pub fn is_skipped(&self) -> bool {
574 matches!(self, BasicResult::Skipped)
575 }
576 pub fn ok_msg(&self) -> Option<&str> {
577 match self {
578 BasicResult::Ok(s) => Some(s),
579 _ => None,
580 }
581 }
582 pub fn err_msg(&self) -> Option<&str> {
583 match self {
584 BasicResult::Err(s) => Some(s),
585 _ => None,
586 }
587 }
588 pub fn progress(&self) -> f64 {
589 match self {
590 BasicResult::Ok(_) => 1.0,
591 BasicResult::Err(_) => 0.0,
592 BasicResult::Skipped => 0.0,
593 BasicResult::Partial { done, total } => {
594 if *total == 0 {
595 0.0
596 } else {
597 *done as f64 / *total as f64
598 }
599 }
600 }
601 }
602}
603#[derive(Clone, Debug)]
605pub struct LocalDecl {
606 pub fvar_id: FVarId,
608 pub user_name: Name,
610 pub ty: Expr,
612 pub binder_info: BinderInfo,
614 pub value: Option<Expr>,
616 pub index: u32,
618}
619#[derive(Clone, Debug)]
621pub struct MetaConfig {
622 pub fo_approx: bool,
624 pub const_approx: bool,
626 pub ctx_approx: bool,
628 pub track_assignments: bool,
630 pub max_recursion_depth: u32,
632 pub proof_irrelevance: bool,
634 pub eta_struct: bool,
636 pub unfold_reducible: bool,
638}
639#[derive(Clone, Debug)]
641pub struct MetaState {
642 pub num_mvars: u64,
644 pub num_locals: u32,
646 pub mvar_assignments: HashMap<MVarId, Expr>,
648 pub level_assignments: HashMap<u64, Level>,
650 pub num_postponed: usize,
652}
653#[derive(Clone, Debug, Default)]
655pub struct LocalContext {
656 pub hyps: Vec<(Name, Expr)>,
658}
659impl LocalContext {
660 pub fn new() -> Self {
662 Self::default()
663 }
664 pub fn add(&mut self, name: Name, ty: Expr) {
666 self.hyps.push((name, ty));
667 }
668 pub fn len(&self) -> usize {
670 self.hyps.len()
671 }
672 pub fn is_empty(&self) -> bool {
674 self.hyps.is_empty()
675 }
676 pub fn get(&self, name: &Name) -> Option<&Expr> {
678 self.hyps.iter().find(|(n, _)| n == name).map(|(_, ty)| ty)
679 }
680 pub fn contains(&self, name: &Name) -> bool {
682 self.hyps.iter().any(|(n, _)| n == name)
683 }
684 pub fn remove(&mut self, name: &Name) -> bool {
686 if let Some(pos) = self.hyps.iter().position(|(n, _)| n == name) {
687 self.hyps.remove(pos);
688 true
689 } else {
690 false
691 }
692 }
693 pub fn names(&self) -> Vec<&Name> {
695 self.hyps.iter().map(|(n, _)| n).collect()
696 }
697}
698#[allow(dead_code)]
700#[derive(Debug, Clone)]
701pub enum BasicConfigValue {
702 Bool(bool),
703 Int(i64),
704 Float(f64),
705 Str(String),
706 List(Vec<String>),
707}
708#[allow(dead_code)]
709impl BasicConfigValue {
710 pub fn as_bool(&self) -> Option<bool> {
711 match self {
712 BasicConfigValue::Bool(b) => Some(*b),
713 _ => None,
714 }
715 }
716 pub fn as_int(&self) -> Option<i64> {
717 match self {
718 BasicConfigValue::Int(i) => Some(*i),
719 _ => None,
720 }
721 }
722 pub fn as_float(&self) -> Option<f64> {
723 match self {
724 BasicConfigValue::Float(f) => Some(*f),
725 _ => None,
726 }
727 }
728 pub fn as_str(&self) -> Option<&str> {
729 match self {
730 BasicConfigValue::Str(s) => Some(s),
731 _ => None,
732 }
733 }
734 pub fn as_list(&self) -> Option<&[String]> {
735 match self {
736 BasicConfigValue::List(v) => Some(v),
737 _ => None,
738 }
739 }
740 pub fn type_name(&self) -> &'static str {
741 match self {
742 BasicConfigValue::Bool(_) => "bool",
743 BasicConfigValue::Int(_) => "int",
744 BasicConfigValue::Float(_) => "float",
745 BasicConfigValue::Str(_) => "str",
746 BasicConfigValue::List(_) => "list",
747 }
748 }
749}
750#[derive(Clone, Debug)]
752pub struct PostponedConstraint {
753 pub lhs: Expr,
755 pub rhs: Expr,
757 pub depth: u32,
759}
760#[derive(Clone, Debug)]
762pub struct UnificationEntry {
763 pub lhs: String,
765 pub rhs: String,
767 pub success: bool,
769 pub depth: u32,
771}
772#[allow(dead_code)]
773#[derive(Debug, Clone)]
774pub enum BasicExtConfigVal3800 {
775 Bool(bool),
776 Int(i64),
777 Float(f64),
778 Str(String),
779 List(Vec<String>),
780}
781impl BasicExtConfigVal3800 {
782 #[allow(dead_code)]
783 pub fn as_bool(&self) -> Option<bool> {
784 if let BasicExtConfigVal3800::Bool(b) = self {
785 Some(*b)
786 } else {
787 None
788 }
789 }
790 #[allow(dead_code)]
791 pub fn as_int(&self) -> Option<i64> {
792 if let BasicExtConfigVal3800::Int(i) = self {
793 Some(*i)
794 } else {
795 None
796 }
797 }
798 #[allow(dead_code)]
799 pub fn as_float(&self) -> Option<f64> {
800 if let BasicExtConfigVal3800::Float(f) = self {
801 Some(*f)
802 } else {
803 None
804 }
805 }
806 #[allow(dead_code)]
807 pub fn as_str(&self) -> Option<&str> {
808 if let BasicExtConfigVal3800::Str(s) = self {
809 Some(s)
810 } else {
811 None
812 }
813 }
814 #[allow(dead_code)]
815 pub fn as_list(&self) -> Option<&[String]> {
816 if let BasicExtConfigVal3800::List(l) = self {
817 Some(l)
818 } else {
819 None
820 }
821 }
822 #[allow(dead_code)]
823 pub fn type_name(&self) -> &'static str {
824 match self {
825 BasicExtConfigVal3800::Bool(_) => "bool",
826 BasicExtConfigVal3800::Int(_) => "int",
827 BasicExtConfigVal3800::Float(_) => "float",
828 BasicExtConfigVal3800::Str(_) => "str",
829 BasicExtConfigVal3800::List(_) => "list",
830 }
831 }
832}
833#[allow(dead_code)]
834pub struct BasicExtDiag3800 {
835 pub errors: Vec<String>,
836 pub warnings: Vec<String>,
837 pub notes: Vec<String>,
838 pub max_errors: usize,
839}
840impl BasicExtDiag3800 {
841 #[allow(dead_code)]
842 pub fn new(max_errors: usize) -> Self {
843 Self {
844 errors: Vec::new(),
845 warnings: Vec::new(),
846 notes: Vec::new(),
847 max_errors,
848 }
849 }
850 #[allow(dead_code)]
851 pub fn error(&mut self, msg: &str) {
852 if self.errors.len() < self.max_errors {
853 self.errors.push(msg.to_string());
854 }
855 }
856 #[allow(dead_code)]
857 pub fn warning(&mut self, msg: &str) {
858 self.warnings.push(msg.to_string());
859 }
860 #[allow(dead_code)]
861 pub fn note(&mut self, msg: &str) {
862 self.notes.push(msg.to_string());
863 }
864 #[allow(dead_code)]
865 pub fn has_errors(&self) -> bool {
866 !self.errors.is_empty()
867 }
868 #[allow(dead_code)]
869 pub fn num_errors(&self) -> usize {
870 self.errors.len()
871 }
872 #[allow(dead_code)]
873 pub fn num_warnings(&self) -> usize {
874 self.warnings.len()
875 }
876 #[allow(dead_code)]
877 pub fn is_clean(&self) -> bool {
878 self.errors.is_empty() && self.warnings.is_empty()
879 }
880 #[allow(dead_code)]
881 pub fn at_error_limit(&self) -> bool {
882 self.errors.len() >= self.max_errors
883 }
884 #[allow(dead_code)]
885 pub fn clear(&mut self) {
886 self.errors.clear();
887 self.warnings.clear();
888 self.notes.clear();
889 }
890 #[allow(dead_code)]
891 pub fn summary(&self) -> String {
892 format!(
893 "{} error(s), {} warning(s)",
894 self.errors.len(),
895 self.warnings.len()
896 )
897 }
898}
899#[derive(Clone, Debug)]
903pub struct MetaVarPool {
904 pub(super) next_id: u64,
905 pub(super) batch_size: usize,
906}
907impl MetaVarPool {
908 pub fn new(start: u64) -> Self {
910 Self {
911 next_id: start,
912 batch_size: 64,
913 }
914 }
915 pub fn with_batch_size(start: u64, batch_size: usize) -> Self {
917 Self {
918 next_id: start,
919 batch_size,
920 }
921 }
922 #[allow(clippy::should_implement_trait)]
924 pub fn next(&mut self) -> u64 {
925 let id = self.next_id;
926 self.next_id += 1;
927 id
928 }
929 pub fn reserve_batch(&mut self) -> (u64, usize) {
931 let start = self.next_id;
932 self.next_id += self.batch_size as u64;
933 (start, self.batch_size)
934 }
935 pub fn count_issued(&self) -> u64 {
937 self.next_id
938 }
939}
940#[allow(dead_code)]
942#[derive(Debug, Clone)]
943pub struct BasicDiff {
944 pub added: Vec<String>,
945 pub removed: Vec<String>,
946 pub unchanged: Vec<String>,
947}
948#[allow(dead_code)]
949impl BasicDiff {
950 pub fn new() -> Self {
951 BasicDiff {
952 added: Vec::new(),
953 removed: Vec::new(),
954 unchanged: Vec::new(),
955 }
956 }
957 pub fn add(&mut self, s: &str) {
958 self.added.push(s.to_string());
959 }
960 pub fn remove(&mut self, s: &str) {
961 self.removed.push(s.to_string());
962 }
963 pub fn keep(&mut self, s: &str) {
964 self.unchanged.push(s.to_string());
965 }
966 pub fn is_empty(&self) -> bool {
967 self.added.is_empty() && self.removed.is_empty()
968 }
969 pub fn total_changes(&self) -> usize {
970 self.added.len() + self.removed.len()
971 }
972 pub fn net_additions(&self) -> i64 {
973 self.added.len() as i64 - self.removed.len() as i64
974 }
975 pub fn summary(&self) -> String {
976 format!(
977 "+{} -{} =={}",
978 self.added.len(),
979 self.removed.len(),
980 self.unchanged.len()
981 )
982 }
983}
984#[allow(dead_code)]
986pub struct MetaBasicBuilder {
987 pub name: String,
988 pub items: Vec<String>,
989 pub config: std::collections::HashMap<String, String>,
990}
991#[allow(dead_code)]
992impl MetaBasicBuilder {
993 pub fn new(name: &str) -> Self {
994 MetaBasicBuilder {
995 name: name.to_string(),
996 items: Vec::new(),
997 config: std::collections::HashMap::new(),
998 }
999 }
1000 pub fn add_item(mut self, item: &str) -> Self {
1001 self.items.push(item.to_string());
1002 self
1003 }
1004 pub fn set_config(mut self, key: &str, value: &str) -> Self {
1005 self.config.insert(key.to_string(), value.to_string());
1006 self
1007 }
1008 pub fn item_count(&self) -> usize {
1009 self.items.len()
1010 }
1011 pub fn has_config(&self, key: &str) -> bool {
1012 self.config.contains_key(key)
1013 }
1014 pub fn get_config(&self, key: &str) -> Option<&str> {
1015 self.config.get(key).map(|s| s.as_str())
1016 }
1017 pub fn build_summary(&self) -> String {
1018 format!(
1019 "{}: {} items, {} config keys",
1020 self.name,
1021 self.items.len(),
1022 self.config.len()
1023 )
1024 }
1025}
1026#[allow(dead_code)]
1028pub struct MetaBasicWorkQueue {
1029 pub pending: std::collections::VecDeque<String>,
1030 pub processed: Vec<String>,
1031 pub capacity: usize,
1032}
1033#[allow(dead_code)]
1034impl MetaBasicWorkQueue {
1035 pub fn new(capacity: usize) -> Self {
1036 MetaBasicWorkQueue {
1037 pending: std::collections::VecDeque::new(),
1038 processed: Vec::new(),
1039 capacity,
1040 }
1041 }
1042 pub fn enqueue(&mut self, item: String) -> bool {
1043 if self.pending.len() >= self.capacity {
1044 return false;
1045 }
1046 self.pending.push_back(item);
1047 true
1048 }
1049 pub fn dequeue(&mut self) -> Option<String> {
1050 let item = self.pending.pop_front()?;
1051 self.processed.push(item.clone());
1052 Some(item)
1053 }
1054 pub fn pending_count(&self) -> usize {
1055 self.pending.len()
1056 }
1057 pub fn processed_count(&self) -> usize {
1058 self.processed.len()
1059 }
1060 pub fn is_empty(&self) -> bool {
1061 self.pending.is_empty()
1062 }
1063 pub fn is_full(&self) -> bool {
1064 self.pending.len() >= self.capacity
1065 }
1066 pub fn total_processed(&self) -> usize {
1067 self.processed.len()
1068 }
1069}
1070#[allow(dead_code)]
1072#[derive(Debug, Clone, PartialEq)]
1073pub enum MetaBasicState {
1074 Initial,
1075 Running,
1076 Paused,
1077 Complete,
1078 Failed(String),
1079}
1080#[allow(dead_code)]
1081impl MetaBasicState {
1082 pub fn is_terminal(&self) -> bool {
1083 matches!(self, MetaBasicState::Complete | MetaBasicState::Failed(_))
1084 }
1085 pub fn can_run(&self) -> bool {
1086 matches!(self, MetaBasicState::Initial | MetaBasicState::Paused)
1087 }
1088 pub fn is_running(&self) -> bool {
1089 matches!(self, MetaBasicState::Running)
1090 }
1091 pub fn error_msg(&self) -> Option<&str> {
1092 match self {
1093 MetaBasicState::Failed(s) => Some(s),
1094 _ => None,
1095 }
1096 }
1097}
1098#[allow(dead_code)]
1100pub struct BasicAnalysisPass {
1101 pub name: String,
1102 pub enabled: bool,
1103 pub results: Vec<BasicResult>,
1104 pub total_runs: usize,
1105}
1106#[allow(dead_code)]
1107impl BasicAnalysisPass {
1108 pub fn new(name: &str) -> Self {
1109 BasicAnalysisPass {
1110 name: name.to_string(),
1111 enabled: true,
1112 results: Vec::new(),
1113 total_runs: 0,
1114 }
1115 }
1116 pub fn run(&mut self, input: &str) -> BasicResult {
1117 self.total_runs += 1;
1118 let result = if input.is_empty() {
1119 BasicResult::Err("empty input".to_string())
1120 } else {
1121 BasicResult::Ok(format!("processed: {}", input))
1122 };
1123 self.results.push(result.clone());
1124 result
1125 }
1126 pub fn success_count(&self) -> usize {
1127 self.results.iter().filter(|r| r.is_ok()).count()
1128 }
1129 pub fn error_count(&self) -> usize {
1130 self.results.iter().filter(|r| r.is_err()).count()
1131 }
1132 pub fn success_rate(&self) -> f64 {
1133 if self.total_runs == 0 {
1134 0.0
1135 } else {
1136 self.success_count() as f64 / self.total_runs as f64
1137 }
1138 }
1139 pub fn disable(&mut self) {
1140 self.enabled = false;
1141 }
1142 pub fn enable(&mut self) {
1143 self.enabled = true;
1144 }
1145 pub fn clear_results(&mut self) {
1146 self.results.clear();
1147 }
1148}
1149#[allow(dead_code)]
1150#[derive(Debug, Clone)]
1151pub enum BasicExtResult3800 {
1152 Ok(String),
1154 Err(String),
1156 Partial { done: usize, total: usize },
1158 Skipped,
1160}
1161impl BasicExtResult3800 {
1162 #[allow(dead_code)]
1163 pub fn is_ok(&self) -> bool {
1164 matches!(self, BasicExtResult3800::Ok(_))
1165 }
1166 #[allow(dead_code)]
1167 pub fn is_err(&self) -> bool {
1168 matches!(self, BasicExtResult3800::Err(_))
1169 }
1170 #[allow(dead_code)]
1171 pub fn is_partial(&self) -> bool {
1172 matches!(self, BasicExtResult3800::Partial { .. })
1173 }
1174 #[allow(dead_code)]
1175 pub fn is_skipped(&self) -> bool {
1176 matches!(self, BasicExtResult3800::Skipped)
1177 }
1178 #[allow(dead_code)]
1179 pub fn ok_msg(&self) -> Option<&str> {
1180 if let BasicExtResult3800::Ok(s) = self {
1181 Some(s)
1182 } else {
1183 None
1184 }
1185 }
1186 #[allow(dead_code)]
1187 pub fn err_msg(&self) -> Option<&str> {
1188 if let BasicExtResult3800::Err(s) = self {
1189 Some(s)
1190 } else {
1191 None
1192 }
1193 }
1194 #[allow(dead_code)]
1195 pub fn progress(&self) -> f64 {
1196 match self {
1197 BasicExtResult3800::Ok(_) => 1.0,
1198 BasicExtResult3800::Err(_) => 0.0,
1199 BasicExtResult3800::Partial { done, total } => {
1200 if *total == 0 {
1201 0.0
1202 } else {
1203 *done as f64 / *total as f64
1204 }
1205 }
1206 BasicExtResult3800::Skipped => 0.5,
1207 }
1208 }
1209}
1210#[allow(dead_code)]
1212pub struct MetaBasicCounterMap {
1213 pub counts: std::collections::HashMap<String, usize>,
1214 pub total: usize,
1215}
1216#[allow(dead_code)]
1217impl MetaBasicCounterMap {
1218 pub fn new() -> Self {
1219 MetaBasicCounterMap {
1220 counts: std::collections::HashMap::new(),
1221 total: 0,
1222 }
1223 }
1224 pub fn increment(&mut self, key: &str) {
1225 *self.counts.entry(key.to_string()).or_insert(0) += 1;
1226 self.total += 1;
1227 }
1228 pub fn count(&self, key: &str) -> usize {
1229 *self.counts.get(key).unwrap_or(&0)
1230 }
1231 pub fn frequency(&self, key: &str) -> f64 {
1232 if self.total == 0 {
1233 0.0
1234 } else {
1235 self.count(key) as f64 / self.total as f64
1236 }
1237 }
1238 pub fn most_common(&self) -> Option<(&String, usize)> {
1239 self.counts
1240 .iter()
1241 .max_by_key(|(_, &v)| v)
1242 .map(|(k, &v)| (k, v))
1243 }
1244 pub fn num_unique(&self) -> usize {
1245 self.counts.len()
1246 }
1247 pub fn is_empty(&self) -> bool {
1248 self.counts.is_empty()
1249 }
1250}
1251#[allow(dead_code)]
1253pub struct BasicPipeline {
1254 pub passes: Vec<BasicAnalysisPass>,
1255 pub name: String,
1256 pub total_inputs_processed: usize,
1257}
1258#[allow(dead_code)]
1259impl BasicPipeline {
1260 pub fn new(name: &str) -> Self {
1261 BasicPipeline {
1262 passes: Vec::new(),
1263 name: name.to_string(),
1264 total_inputs_processed: 0,
1265 }
1266 }
1267 pub fn add_pass(&mut self, pass: BasicAnalysisPass) {
1268 self.passes.push(pass);
1269 }
1270 pub fn run_all(&mut self, input: &str) -> Vec<BasicResult> {
1271 self.total_inputs_processed += 1;
1272 self.passes
1273 .iter_mut()
1274 .filter(|p| p.enabled)
1275 .map(|p| p.run(input))
1276 .collect()
1277 }
1278 pub fn num_passes(&self) -> usize {
1279 self.passes.len()
1280 }
1281 pub fn num_enabled_passes(&self) -> usize {
1282 self.passes.iter().filter(|p| p.enabled).count()
1283 }
1284 pub fn total_success_rate(&self) -> f64 {
1285 if self.passes.is_empty() {
1286 0.0
1287 } else {
1288 let total_rate: f64 = self.passes.iter().map(|p| p.success_rate()).sum();
1289 total_rate / self.passes.len() as f64
1290 }
1291 }
1292}
1293#[allow(dead_code)]
1294pub struct BasicExtPass3800 {
1295 pub name: String,
1296 pub total_runs: usize,
1297 pub successes: usize,
1298 pub errors: usize,
1299 pub enabled: bool,
1300 pub results: Vec<BasicExtResult3800>,
1301}
1302impl BasicExtPass3800 {
1303 #[allow(dead_code)]
1304 pub fn new(name: &str) -> Self {
1305 Self {
1306 name: name.to_string(),
1307 total_runs: 0,
1308 successes: 0,
1309 errors: 0,
1310 enabled: true,
1311 results: Vec::new(),
1312 }
1313 }
1314 #[allow(dead_code)]
1315 pub fn run(&mut self, input: &str) -> BasicExtResult3800 {
1316 if !self.enabled {
1317 return BasicExtResult3800::Skipped;
1318 }
1319 self.total_runs += 1;
1320 let result = if input.is_empty() {
1321 self.errors += 1;
1322 BasicExtResult3800::Err(format!("empty input in pass '{}'", self.name))
1323 } else {
1324 self.successes += 1;
1325 BasicExtResult3800::Ok(format!(
1326 "processed {} chars in pass '{}'",
1327 input.len(),
1328 self.name
1329 ))
1330 };
1331 self.results.push(result.clone());
1332 result
1333 }
1334 #[allow(dead_code)]
1335 pub fn success_count(&self) -> usize {
1336 self.successes
1337 }
1338 #[allow(dead_code)]
1339 pub fn error_count(&self) -> usize {
1340 self.errors
1341 }
1342 #[allow(dead_code)]
1343 pub fn success_rate(&self) -> f64 {
1344 if self.total_runs == 0 {
1345 0.0
1346 } else {
1347 self.successes as f64 / self.total_runs as f64
1348 }
1349 }
1350 #[allow(dead_code)]
1351 pub fn disable(&mut self) {
1352 self.enabled = false;
1353 }
1354 #[allow(dead_code)]
1355 pub fn enable(&mut self) {
1356 self.enabled = true;
1357 }
1358 #[allow(dead_code)]
1359 pub fn clear_results(&mut self) {
1360 self.results.clear();
1361 }
1362}
1363#[allow(dead_code)]
1364pub struct BasicExtPipeline3800 {
1365 pub name: String,
1366 pub passes: Vec<BasicExtPass3800>,
1367 pub run_count: usize,
1368}
1369impl BasicExtPipeline3800 {
1370 #[allow(dead_code)]
1371 pub fn new(name: &str) -> Self {
1372 Self {
1373 name: name.to_string(),
1374 passes: Vec::new(),
1375 run_count: 0,
1376 }
1377 }
1378 #[allow(dead_code)]
1379 pub fn add_pass(&mut self, pass: BasicExtPass3800) {
1380 self.passes.push(pass);
1381 }
1382 #[allow(dead_code)]
1383 pub fn run_all(&mut self, input: &str) -> Vec<BasicExtResult3800> {
1384 self.run_count += 1;
1385 self.passes
1386 .iter_mut()
1387 .filter(|p| p.enabled)
1388 .map(|p| p.run(input))
1389 .collect()
1390 }
1391 #[allow(dead_code)]
1392 pub fn num_passes(&self) -> usize {
1393 self.passes.len()
1394 }
1395 #[allow(dead_code)]
1396 pub fn num_enabled_passes(&self) -> usize {
1397 self.passes.iter().filter(|p| p.enabled).count()
1398 }
1399 #[allow(dead_code)]
1400 pub fn total_success_rate(&self) -> f64 {
1401 let total: usize = self.passes.iter().map(|p| p.total_runs).sum();
1402 let ok: usize = self.passes.iter().map(|p| p.successes).sum();
1403 if total == 0 {
1404 0.0
1405 } else {
1406 ok as f64 / total as f64
1407 }
1408 }
1409}
1410#[allow(dead_code)]
1411pub struct BasicExtConfig3800 {
1412 pub(super) values: std::collections::HashMap<String, BasicExtConfigVal3800>,
1413 pub(super) read_only: bool,
1414 pub(super) name: String,
1415}
1416impl BasicExtConfig3800 {
1417 #[allow(dead_code)]
1418 pub fn new() -> Self {
1419 Self {
1420 values: std::collections::HashMap::new(),
1421 read_only: false,
1422 name: String::new(),
1423 }
1424 }
1425 #[allow(dead_code)]
1426 pub fn named(name: &str) -> Self {
1427 Self {
1428 values: std::collections::HashMap::new(),
1429 read_only: false,
1430 name: name.to_string(),
1431 }
1432 }
1433 #[allow(dead_code)]
1434 pub fn set(&mut self, key: &str, value: BasicExtConfigVal3800) -> bool {
1435 if self.read_only {
1436 return false;
1437 }
1438 self.values.insert(key.to_string(), value);
1439 true
1440 }
1441 #[allow(dead_code)]
1442 pub fn get(&self, key: &str) -> Option<&BasicExtConfigVal3800> {
1443 self.values.get(key)
1444 }
1445 #[allow(dead_code)]
1446 pub fn get_bool(&self, key: &str) -> Option<bool> {
1447 self.get(key)?.as_bool()
1448 }
1449 #[allow(dead_code)]
1450 pub fn get_int(&self, key: &str) -> Option<i64> {
1451 self.get(key)?.as_int()
1452 }
1453 #[allow(dead_code)]
1454 pub fn get_str(&self, key: &str) -> Option<&str> {
1455 self.get(key)?.as_str()
1456 }
1457 #[allow(dead_code)]
1458 pub fn set_bool(&mut self, key: &str, v: bool) -> bool {
1459 self.set(key, BasicExtConfigVal3800::Bool(v))
1460 }
1461 #[allow(dead_code)]
1462 pub fn set_int(&mut self, key: &str, v: i64) -> bool {
1463 self.set(key, BasicExtConfigVal3800::Int(v))
1464 }
1465 #[allow(dead_code)]
1466 pub fn set_str(&mut self, key: &str, v: &str) -> bool {
1467 self.set(key, BasicExtConfigVal3800::Str(v.to_string()))
1468 }
1469 #[allow(dead_code)]
1470 pub fn lock(&mut self) {
1471 self.read_only = true;
1472 }
1473 #[allow(dead_code)]
1474 pub fn unlock(&mut self) {
1475 self.read_only = false;
1476 }
1477 #[allow(dead_code)]
1478 pub fn size(&self) -> usize {
1479 self.values.len()
1480 }
1481 #[allow(dead_code)]
1482 pub fn has(&self, key: &str) -> bool {
1483 self.values.contains_key(key)
1484 }
1485 #[allow(dead_code)]
1486 pub fn remove(&mut self, key: &str) -> bool {
1487 self.values.remove(key).is_some()
1488 }
1489}