halo2_proofs/dev/
metadata.rs

1//! Metadata about circuits.
2
3use crate::plonk::{self, Any};
4use std::fmt;
5
6/// Metadata about a column within a circuit.
7#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
8pub struct Column {
9    /// The type of the column.
10    pub(super) column_type: Any,
11    /// The index of the column.
12    pub(super) index: usize,
13}
14
15impl fmt::Display for Column {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        write!(f, "Column('{:?}', {})", self.column_type, self.index)
18    }
19}
20
21impl From<(Any, usize)> for Column {
22    fn from((column_type, index): (Any, usize)) -> Self {
23        Column { column_type, index }
24    }
25}
26
27impl From<plonk::Column<Any>> for Column {
28    fn from(column: plonk::Column<Any>) -> Self {
29        Column {
30            column_type: *column.column_type(),
31            index: column.index(),
32        }
33    }
34}
35
36/// A "virtual cell" is a PLONK cell that has been queried at a particular relative offset
37/// within a custom gate.
38#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
39pub struct VirtualCell {
40    name: &'static str,
41    pub(super) column: Column,
42    pub(super) rotation: i32,
43}
44
45impl From<(Column, i32)> for VirtualCell {
46    fn from((column, rotation): (Column, i32)) -> Self {
47        VirtualCell {
48            name: "",
49            column,
50            rotation,
51        }
52    }
53}
54
55impl From<(&'static str, Column, i32)> for VirtualCell {
56    fn from((name, column, rotation): (&'static str, Column, i32)) -> Self {
57        VirtualCell {
58            name,
59            column,
60            rotation,
61        }
62    }
63}
64
65impl From<plonk::VirtualCell> for VirtualCell {
66    fn from(c: plonk::VirtualCell) -> Self {
67        VirtualCell {
68            name: "",
69            column: c.column.into(),
70            rotation: c.rotation.0,
71        }
72    }
73}
74
75impl fmt::Display for VirtualCell {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        write!(f, "{}@{}", self.column, self.rotation)?;
78        if !self.name.is_empty() {
79            write!(f, "({})", self.name)?;
80        }
81        Ok(())
82    }
83}
84
85/// Metadata about a configured gate within a circuit.
86#[derive(Debug, PartialEq)]
87pub struct Gate {
88    /// The index of the active gate. These indices are assigned in the order in which
89    /// `ConstraintSystem::create_gate` is called during `Circuit::configure`.
90    pub(super) index: usize,
91    /// The name of the active gate. These are specified by the gate creator (such as
92    /// a chip implementation), and is not enforced to be unique.
93    pub(super) name: &'static str,
94}
95
96impl fmt::Display for Gate {
97    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98        write!(f, "Gate {} ('{}')", self.index, self.name)
99    }
100}
101
102impl From<(usize, &'static str)> for Gate {
103    fn from((index, name): (usize, &'static str)) -> Self {
104        Gate { index, name }
105    }
106}
107
108/// Metadata about a configured constraint within a circuit.
109#[derive(Debug, PartialEq)]
110pub struct Constraint {
111    /// The gate containing the constraint.
112    pub(super) gate: Gate,
113    /// The index of the polynomial constraint within the gate. These indices correspond
114    /// to the order in which the constraints are returned from the closure passed to
115    /// `ConstraintSystem::create_gate` during `Circuit::configure`.
116    pub(super) index: usize,
117    /// The name of the constraint. This is specified by the gate creator (such as a chip
118    /// implementation), and is not enforced to be unique.
119    pub(super) name: &'static str,
120}
121
122impl fmt::Display for Constraint {
123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124        write!(
125            f,
126            "Constraint {}{} in gate {} ('{}')",
127            self.index,
128            if self.name.is_empty() {
129                String::new()
130            } else {
131                format!(" ('{}')", self.name)
132            },
133            self.gate.index,
134            self.gate.name,
135        )
136    }
137}
138
139impl From<(Gate, usize, &'static str)> for Constraint {
140    fn from((gate, index, name): (Gate, usize, &'static str)) -> Self {
141        Constraint { gate, index, name }
142    }
143}
144
145/// Metadata about an assigned region within a circuit.
146#[derive(Clone, Debug, PartialEq)]
147pub struct Region {
148    /// The index of the region. These indices are assigned in the order in which
149    /// `Layouter::assign_region` is called during `Circuit::synthesize`.
150    pub(super) index: usize,
151    /// The name of the region. This is specified by the region creator (such as a chip
152    /// implementation), and is not enforced to be unique.
153    pub(super) name: String,
154}
155
156impl fmt::Display for Region {
157    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158        write!(f, "Region {} ('{}')", self.index, self.name)
159    }
160}
161
162impl From<(usize, String)> for Region {
163    fn from((index, name): (usize, String)) -> Self {
164        Region { index, name }
165    }
166}
167
168impl From<(usize, &str)> for Region {
169    fn from((index, name): (usize, &str)) -> Self {
170        Region {
171            index,
172            name: name.to_owned(),
173        }
174    }
175}