openvm_stark_backend/interaction/
debug.rs

1use std::collections::{BTreeMap, HashMap};
2
3use itertools::Itertools;
4use p3_field::Field;
5use p3_matrix::{dense::RowMajorMatrixView, Matrix};
6
7use super::{trace::Evaluator, BusIndex, SymbolicInteraction};
8use crate::air_builders::symbolic::symbolic_expression::SymbolicEvaluator;
9
10/// The actual interactions that are sent/received during a single run
11/// of trace generation. For debugging purposes only.
12#[derive(Default, Clone, Debug)]
13pub struct LogicalInteractions<F: Field> {
14    /// Bus index => (fields => (air_idx, count))
15    #[allow(clippy::type_complexity)]
16    pub at_bus: BTreeMap<BusIndex, HashMap<Vec<F>, Vec<(usize, F)>>>,
17}
18
19pub fn generate_logical_interactions<F: Field>(
20    air_idx: usize,
21    all_interactions: &[SymbolicInteraction<F>],
22    preprocessed: &Option<RowMajorMatrixView<F>>,
23    partitioned_main: &[RowMajorMatrixView<F>],
24    public_values: &[F],
25    logical_interactions: &mut LogicalInteractions<F>,
26) {
27    if all_interactions.is_empty() {
28        return;
29    }
30
31    let height = partitioned_main[0].height();
32
33    for n in 0..height {
34        let evaluator = Evaluator {
35            preprocessed,
36            partitioned_main,
37            public_values,
38            height,
39            local_index: n,
40        };
41        for interaction in all_interactions {
42            let fields = interaction
43                .message
44                .iter()
45                .map(|expr| evaluator.eval_expr(expr))
46                .collect_vec();
47            let count = evaluator.eval_expr(&interaction.count);
48            if count.is_zero() {
49                continue;
50            }
51            logical_interactions
52                .at_bus
53                .entry(interaction.bus_index)
54                .or_default()
55                .entry(fields)
56                .or_default()
57                .push((air_idx, count));
58        }
59    }
60}