sp1_stark/lookup/
interaction.rs

1use core::fmt::{Debug, Display};
2
3use p3_air::VirtualPairCol;
4use p3_field::Field;
5
6use crate::air::InteractionScope;
7
8/// An interaction for a lookup or a permutation argument.
9#[derive(Clone)]
10pub struct Interaction<F: Field> {
11    /// The values of the interaction.
12    pub values: Vec<VirtualPairCol<F>>,
13    /// The multiplicity of the interaction.
14    pub multiplicity: VirtualPairCol<F>,
15    /// The kind of interaction.
16    pub kind: InteractionKind,
17    /// The scope of the interaction.
18    pub scope: InteractionScope,
19}
20
21/// The type of interaction for a lookup argument.
22#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
23pub enum InteractionKind {
24    /// Interaction with the memory table, such as read and write.
25    Memory = 1,
26
27    /// Interaction with the program table, loading an instruction at a given pc address.
28    Program = 2,
29
30    /// Interaction with instruction oracle.
31    Instruction = 3,
32
33    /// Interaction with the ALU operations.
34    Alu = 4,
35
36    /// Interaction with the byte lookup table for byte operations.
37    Byte = 5,
38
39    /// Requesting a range check for a given value and range.
40    Range = 6,
41
42    /// Interaction with the field op table for field operations.
43    Field = 7,
44
45    /// Interaction with a syscall.
46    Syscall = 8,
47
48    /// Interaction with the global table.
49    Global = 9,
50}
51
52impl InteractionKind {
53    /// Returns all kinds of interactions.
54    #[must_use]
55    pub fn all_kinds() -> Vec<InteractionKind> {
56        vec![
57            InteractionKind::Memory,
58            InteractionKind::Program,
59            InteractionKind::Instruction,
60            InteractionKind::Alu,
61            InteractionKind::Byte,
62            InteractionKind::Range,
63            InteractionKind::Field,
64            InteractionKind::Syscall,
65            InteractionKind::Global,
66        ]
67    }
68}
69
70impl<F: Field> Interaction<F> {
71    /// Create a new interaction.
72    pub const fn new(
73        values: Vec<VirtualPairCol<F>>,
74        multiplicity: VirtualPairCol<F>,
75        kind: InteractionKind,
76        scope: InteractionScope,
77    ) -> Self {
78        Self { values, multiplicity, kind, scope }
79    }
80
81    /// The index of the argument in the lookup table.
82    pub const fn argument_index(&self) -> usize {
83        self.kind as usize
84    }
85}
86
87impl<F: Field> Debug for Interaction<F> {
88    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89        f.debug_struct("Interaction")
90            .field("kind", &self.kind)
91            .field("scope", &self.scope)
92            .finish_non_exhaustive()
93    }
94}
95
96impl Display for InteractionKind {
97    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98        match self {
99            InteractionKind::Memory => write!(f, "Memory"),
100            InteractionKind::Program => write!(f, "Program"),
101            InteractionKind::Instruction => write!(f, "Instruction"),
102            InteractionKind::Alu => write!(f, "Alu"),
103            InteractionKind::Byte => write!(f, "Byte"),
104            InteractionKind::Range => write!(f, "Range"),
105            InteractionKind::Field => write!(f, "Field"),
106            InteractionKind::Syscall => write!(f, "Syscall"),
107            InteractionKind::Global => write!(f, "Global"),
108        }
109    }
110}