smt_scope/analysis/
problem_behaviour.rs1use crate::{items::QuantPat, Z3Parser};
2
3use super::{analysis::matching_loop::MlData, InstGraph, RedundancyAnalysis};
4
5#[derive(Debug, Default)]
6pub struct ProblemBehaviours {
7 pub errors: Vec<ProblemBehaviour>,
9 pub warnings: Vec<ProblemBehaviour>,
11}
12
13impl ProblemBehaviours {
14 pub fn find(ml: &MlData, redundancy: &RedundancyAnalysis) -> Self {
15 let mut self_ = Self::default();
16 for (idx, ml) in ml.matching_loops.iter().enumerate() {
17 let kind = PbKind::MatchingLoop {
18 max_len: ml.leaves.0[0].0,
19 idx,
20 };
21 if ml.graph.is_some() {
22 self_.errors.push(ProblemBehaviour { kind, sus: false });
23 } else {
24 self_.warnings.push(ProblemBehaviour { kind, sus: true });
25 }
26 }
27 for (qpat, red) in redundancy.per_quant.iter_enumerated() {
28 let multiplicativity = red.input_multiplicativity();
29 let kind = PbKind::Multiplicative {
30 qpat,
31 multiplicativity,
32 };
33 if multiplicativity >= 4.0 {
34 self_.errors.push(ProblemBehaviour { kind, sus: false });
35 } else if multiplicativity >= 2.0 {
36 self_.warnings.push(ProblemBehaviour { kind, sus: true });
37 }
38 }
39 self_
40 }
41}
42
43#[derive(Debug)]
44pub struct ProblemBehaviour {
45 pub kind: PbKind,
46 pub sus: bool,
48}
49
50#[derive(Debug)]
51pub enum PbKind {
52 MatchingLoop {
53 max_len: u32,
54 idx: usize,
55 },
56 Multiplicative {
57 qpat: QuantPat,
58 multiplicativity: f64,
59 },
60}
61
62impl ProblemBehaviour {
63 pub fn kind_str(&self) -> &'static str {
64 match &self.kind {
65 PbKind::MatchingLoop { .. } => "matching loop",
66 PbKind::Multiplicative { .. } => "multiplicative",
67 }
68 }
69
70 pub fn detail(&self) -> String {
71 match &self.kind {
72 PbKind::MatchingLoop { max_len, .. } => format!("{max_len} iters"),
73 PbKind::Multiplicative {
74 multiplicativity, ..
75 } => {
76 format!("{multiplicativity:.1}x")
77 }
78 }
79 }
80
81 pub fn quant_pats(&self, parser: &Z3Parser, inst: &InstGraph) -> Vec<QuantPat> {
82 match &self.kind {
83 PbKind::MatchingLoop { idx, .. } => {
84 let ml_data = inst.analysis.ml_data.as_ref().unwrap();
85 ml_data.matching_loops[*idx].quants(parser, ml_data)
86 }
87 PbKind::Multiplicative { qpat, .. } => vec![*qpat],
88 }
89 }
90}