kimchi_msm/
columns.rs

1use std::collections::HashMap;
2
3use kimchi::circuits::expr::{CacheId, FormattedOutput};
4
5/// Describe a generic indexed variable X_{i}.
6#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
7pub enum Column<T> {
8    /// Columns related to the relation encoded in the circuit
9    Relation(T),
10    /// Columns related to dynamic selectors to indicate gate type
11    DynamicSelector(usize),
12    /// Constant column that is /always/ fixed for a given circuit.
13    FixedSelector(usize),
14    // Columns related to the lookup protocol
15    /// Partial sums. This corresponds to the `h_i`.
16    /// It is first indexed by the table ID, and after that internal index.
17    LookupPartialSum((u32, usize)),
18    /// Multiplicities, indexed. This corresponds to the `m_i`. First
19    /// indexed by table ID, then internal index.
20    LookupMultiplicity((u32, usize)),
21    /// The lookup aggregation, i.e. `phi`
22    LookupAggregation,
23    /// The fixed tables. The parameter is considered to the indexed table.
24    LookupFixedTable(u32),
25}
26
27impl Column<usize> {
28    /// Adds offset if the column is `Relation`. Fails otherwise.
29    pub fn add_rel_offset(self, offset: usize) -> Column<usize> {
30        let Column::Relation(i) = self else {
31            todo!("add_rel_offset is only implemented for the relation columns")
32        };
33        Column::Relation(offset + i)
34    }
35}
36
37impl FormattedOutput for Column<usize> {
38    fn latex(&self, _cache: &mut HashMap<CacheId, Self>) -> String {
39        match self {
40            Column::Relation(i) => format!("x_{{{i}}}"),
41            Column::FixedSelector(i) => format!("fs_{{{i}}}"),
42            Column::DynamicSelector(i) => format!("ds_{{{i}}}"),
43            Column::LookupPartialSum((table_id, i)) => format!("h_{{{table_id}, {i}}}"),
44            Column::LookupMultiplicity((table_id, i)) => format!("m_{{{table_id}, {i}}}"),
45            Column::LookupFixedTable(i) => format!("t_{{{i}}}"),
46            Column::LookupAggregation => String::from("φ"),
47        }
48    }
49
50    fn text(&self, _cache: &mut HashMap<CacheId, Self>) -> String {
51        match self {
52            Column::Relation(i) => format!("x[{i}]"),
53            Column::FixedSelector(i) => format!("fs[{i}]"),
54            Column::DynamicSelector(i) => format!("ds[{i}]"),
55            Column::LookupPartialSum((table_id, i)) => format!("h[{table_id}, {i}]"),
56            Column::LookupMultiplicity((table_id, i)) => format!("m[{table_id}, {i}]"),
57            Column::LookupFixedTable(i) => format!("t[{i}]"),
58            Column::LookupAggregation => String::from("φ"),
59        }
60    }
61
62    fn ocaml(&self, _cache: &mut HashMap<CacheId, Self>) -> String {
63        // FIXME
64        unimplemented!("Not used at the moment")
65    }
66
67    fn is_alpha(&self) -> bool {
68        // FIXME
69        unimplemented!("Not used at the moment")
70    }
71}
72
73/// A datatype expressing a generalized column, but with potentially
74/// more convenient interface than a bare column.
75pub trait ColumnIndexer<T>: core::fmt::Debug + Copy + Eq + Ord {
76    /// Total number of columns in this index.
77    const N_COL: usize;
78
79    /// Flatten the column "alias" into the integer-like column.
80    fn to_column(self) -> Column<T>;
81}