halo2_proofs/plonk/
circuit.rs

1use core::cmp::max;
2use core::ops::{Add, Mul};
3use ff::Field;
4use std::{
5    convert::TryFrom,
6    ops::{Neg, Sub},
7};
8
9use super::{lookup, permutation, Assigned, Error};
10use crate::circuit::Layouter;
11use crate::{circuit::Region, poly::Rotation};
12
13mod compress_selectors;
14
15/// A column type
16pub trait ColumnType:
17    'static + Sized + Copy + std::fmt::Debug + PartialEq + Eq + Into<Any>
18{
19}
20
21/// A column with an index and type
22#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
23pub struct Column<C: ColumnType> {
24    index: usize,
25    column_type: C,
26}
27
28impl<C: ColumnType> Column<C> {
29    #[cfg(test)]
30    pub(crate) fn new(index: usize, column_type: C) -> Self {
31        Column { index, column_type }
32    }
33
34    pub(crate) fn index(&self) -> usize {
35        self.index
36    }
37
38    /// Type of this column.
39    pub fn column_type(&self) -> &C {
40        &self.column_type
41    }
42}
43
44impl<C: ColumnType> Ord for Column<C> {
45    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
46        // This ordering is consensus-critical! The layouters rely on deterministic column
47        // orderings.
48        match self.column_type.into().cmp(&other.column_type.into()) {
49            // Indices are assigned within column types.
50            std::cmp::Ordering::Equal => self.index.cmp(&other.index),
51            order => order,
52        }
53    }
54}
55
56impl<C: ColumnType> PartialOrd for Column<C> {
57    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
58        Some(self.cmp(other))
59    }
60}
61
62/// An advice column
63#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
64pub struct Advice;
65
66/// A fixed column
67#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
68pub struct Fixed;
69
70/// An instance column
71#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
72pub struct Instance;
73
74/// An enum over the Advice, Fixed, Instance structs
75#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
76pub enum Any {
77    /// An Advice variant
78    Advice,
79    /// A Fixed variant
80    Fixed,
81    /// An Instance variant
82    Instance,
83}
84
85impl Ord for Any {
86    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
87        // This ordering is consensus-critical! The layouters rely on deterministic column
88        // orderings.
89        match (self, other) {
90            (Any::Instance, Any::Instance)
91            | (Any::Advice, Any::Advice)
92            | (Any::Fixed, Any::Fixed) => std::cmp::Ordering::Equal,
93            // Across column types, sort Instance < Advice < Fixed.
94            (Any::Instance, Any::Advice)
95            | (Any::Advice, Any::Fixed)
96            | (Any::Instance, Any::Fixed) => std::cmp::Ordering::Less,
97            (Any::Fixed, Any::Instance)
98            | (Any::Fixed, Any::Advice)
99            | (Any::Advice, Any::Instance) => std::cmp::Ordering::Greater,
100        }
101    }
102}
103
104impl PartialOrd for Any {
105    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
106        Some(self.cmp(other))
107    }
108}
109
110impl ColumnType for Advice {}
111impl ColumnType for Fixed {}
112impl ColumnType for Instance {}
113impl ColumnType for Any {}
114
115impl From<Advice> for Any {
116    fn from(_: Advice) -> Any {
117        Any::Advice
118    }
119}
120
121impl From<Fixed> for Any {
122    fn from(_: Fixed) -> Any {
123        Any::Fixed
124    }
125}
126
127impl From<Instance> for Any {
128    fn from(_: Instance) -> Any {
129        Any::Instance
130    }
131}
132
133impl From<Column<Advice>> for Column<Any> {
134    fn from(advice: Column<Advice>) -> Column<Any> {
135        Column {
136            index: advice.index(),
137            column_type: Any::Advice,
138        }
139    }
140}
141
142impl From<Column<Fixed>> for Column<Any> {
143    fn from(advice: Column<Fixed>) -> Column<Any> {
144        Column {
145            index: advice.index(),
146            column_type: Any::Fixed,
147        }
148    }
149}
150
151impl From<Column<Instance>> for Column<Any> {
152    fn from(advice: Column<Instance>) -> Column<Any> {
153        Column {
154            index: advice.index(),
155            column_type: Any::Instance,
156        }
157    }
158}
159
160impl TryFrom<Column<Any>> for Column<Advice> {
161    type Error = &'static str;
162
163    fn try_from(any: Column<Any>) -> Result<Self, Self::Error> {
164        match any.column_type() {
165            Any::Advice => Ok(Column {
166                index: any.index(),
167                column_type: Advice,
168            }),
169            _ => Err("Cannot convert into Column<Advice>"),
170        }
171    }
172}
173
174impl TryFrom<Column<Any>> for Column<Fixed> {
175    type Error = &'static str;
176
177    fn try_from(any: Column<Any>) -> Result<Self, Self::Error> {
178        match any.column_type() {
179            Any::Fixed => Ok(Column {
180                index: any.index(),
181                column_type: Fixed,
182            }),
183            _ => Err("Cannot convert into Column<Fixed>"),
184        }
185    }
186}
187
188impl TryFrom<Column<Any>> for Column<Instance> {
189    type Error = &'static str;
190
191    fn try_from(any: Column<Any>) -> Result<Self, Self::Error> {
192        match any.column_type() {
193            Any::Instance => Ok(Column {
194                index: any.index(),
195                column_type: Instance,
196            }),
197            _ => Err("Cannot convert into Column<Instance>"),
198        }
199    }
200}
201
202/// A selector, representing a fixed boolean value per row of the circuit.
203///
204/// Selectors can be used to conditionally enable (portions of) gates:
205/// ```
206/// use halo2_proofs::poly::Rotation;
207/// # use halo2_proofs::pasta::Fp;
208/// # use halo2_proofs::plonk::ConstraintSystem;
209///
210/// # let mut meta = ConstraintSystem::<Fp>::default();
211/// let a = meta.advice_column();
212/// let b = meta.advice_column();
213/// let s = meta.selector();
214///
215/// meta.create_gate("foo", |meta| {
216///     let a = meta.query_advice(a, Rotation::prev());
217///     let b = meta.query_advice(b, Rotation::cur());
218///     let s = meta.query_selector(s);
219///
220///     // On rows where the selector is enabled, a is constrained to equal b.
221///     // On rows where the selector is disabled, a and b can take any value.
222///     vec![s * (a - b)]
223/// });
224/// ```
225///
226/// Selectors are disabled on all rows by default, and must be explicitly enabled on each
227/// row when required:
228/// ```
229/// use halo2_proofs::{arithmetic::FieldExt, circuit::{Chip, Layouter}, plonk::{Advice, Column, Error, Selector}};
230/// # use ff::Field;
231/// # use halo2_proofs::plonk::Fixed;
232///
233/// struct Config {
234///     a: Column<Advice>,
235///     b: Column<Advice>,
236///     s: Selector,
237/// }
238///
239/// fn circuit_logic<F: FieldExt, C: Chip<F>>(chip: C, mut layouter: impl Layouter<F>) -> Result<(), Error> {
240///     let config = chip.config();
241///     # let config: Config = todo!();
242///     layouter.assign_region(|| "bar", |mut region| {
243///         region.assign_advice(|| "a", config.a, 0, || Ok(F::one()))?;
244///         region.assign_advice(|| "a", config.b, 1, || Ok(F::one()))?;
245///         config.s.enable(&mut region, 1)
246///     })?;
247///     Ok(())
248/// }
249/// ```
250#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
251pub struct Selector(pub(crate) usize, bool);
252
253impl Selector {
254    /// Enable this selector at the given offset within the given region.
255    pub fn enable<F: Field>(&self, region: &mut Region<F>, offset: usize) -> Result<(), Error> {
256        region.enable_selector(|| "", self, offset)
257    }
258
259    /// Is this selector "simple"? Simple selectors can only be multiplied
260    /// by expressions that contain no other simple selectors.
261    pub fn is_simple(&self) -> bool {
262        self.1
263    }
264}
265
266/// A fixed column of a lookup table.
267///
268/// A lookup table can be loaded into this column via [`Layouter::assign_table`]. Columns
269/// can currently only contain a single table, but they may be used in multiple lookup
270/// arguments via [`ConstraintSystem::lookup`].
271///
272/// Lookup table columns are always "encumbered" by the lookup arguments they are used in;
273/// they cannot simultaneously be used as general fixed columns.
274///
275/// [`Layouter::assign_table`]: crate::circuit::Layouter::assign_table
276#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
277pub struct TableColumn {
278    /// The fixed column that this table column is stored in.
279    ///
280    /// # Security
281    ///
282    /// This inner column MUST NOT be exposed in the public API, or else chip developers
283    /// can load lookup tables into their circuits without default-value-filling the
284    /// columns, which can cause soundness bugs.
285    inner: Column<Fixed>,
286}
287
288impl TableColumn {
289    pub(crate) fn inner(&self) -> Column<Fixed> {
290        self.inner
291    }
292}
293
294/// This trait allows a [`Circuit`] to direct some backend to assign a witness
295/// for a constraint system.
296pub trait Assignment<F: Field> {
297    /// Creates a new region and enters into it.
298    ///
299    /// Panics if we are currently in a region (if `exit_region` was not called).
300    ///
301    /// Not intended for downstream consumption; use [`Layouter::assign_region`] instead.
302    ///
303    /// [`Layouter::assign_region`]: crate::circuit::Layouter#method.assign_region
304    fn enter_region<NR, N>(&mut self, name_fn: N)
305    where
306        NR: Into<String>,
307        N: FnOnce() -> NR;
308
309    /// Exits the current region.
310    ///
311    /// Panics if we are not currently in a region (if `enter_region` was not called).
312    ///
313    /// Not intended for downstream consumption; use [`Layouter::assign_region`] instead.
314    ///
315    /// [`Layouter::assign_region`]: crate::circuit::Layouter#method.assign_region
316    fn exit_region(&mut self);
317
318    /// Enables a selector at the given row.
319    fn enable_selector<A, AR>(
320        &mut self,
321        annotation: A,
322        selector: &Selector,
323        row: usize,
324    ) -> Result<(), Error>
325    where
326        A: FnOnce() -> AR,
327        AR: Into<String>;
328
329    /// Queries the cell of an instance column at a particular absolute row.
330    ///
331    /// Returns the cell's value, if known.
332    fn query_instance(&self, column: Column<Instance>, row: usize) -> Result<Option<F>, Error>;
333
334    /// Assign an advice column value (witness)
335    fn assign_advice<V, VR, A, AR>(
336        &mut self,
337        annotation: A,
338        column: Column<Advice>,
339        row: usize,
340        to: V,
341    ) -> Result<(), Error>
342    where
343        V: FnOnce() -> Result<VR, Error>,
344        VR: Into<Assigned<F>>,
345        A: FnOnce() -> AR,
346        AR: Into<String>;
347
348    /// Assign a fixed value
349    fn assign_fixed<V, VR, A, AR>(
350        &mut self,
351        annotation: A,
352        column: Column<Fixed>,
353        row: usize,
354        to: V,
355    ) -> Result<(), Error>
356    where
357        V: FnOnce() -> Result<VR, Error>,
358        VR: Into<Assigned<F>>,
359        A: FnOnce() -> AR,
360        AR: Into<String>;
361
362    /// Assign two cells to have the same value
363    fn copy(
364        &mut self,
365        left_column: Column<Any>,
366        left_row: usize,
367        right_column: Column<Any>,
368        right_row: usize,
369    ) -> Result<(), Error>;
370
371    /// Fills a fixed `column` starting from the given `row` with value `to`.
372    fn fill_from_row(
373        &mut self,
374        column: Column<Fixed>,
375        row: usize,
376        to: Option<Assigned<F>>,
377    ) -> Result<(), Error>;
378
379    /// Creates a new (sub)namespace and enters into it.
380    ///
381    /// Not intended for downstream consumption; use [`Layouter::namespace`] instead.
382    ///
383    /// [`Layouter::namespace`]: crate::circuit::Layouter#method.namespace
384    fn push_namespace<NR, N>(&mut self, name_fn: N)
385    where
386        NR: Into<String>,
387        N: FnOnce() -> NR;
388
389    /// Exits out of the existing namespace.
390    ///
391    /// Not intended for downstream consumption; use [`Layouter::namespace`] instead.
392    ///
393    /// [`Layouter::namespace`]: crate::circuit::Layouter#method.namespace
394    fn pop_namespace(&mut self, gadget_name: Option<String>);
395}
396
397/// A floor planning strategy for a circuit.
398///
399/// The floor planner is chip-agnostic and applies its strategy to the circuit it is used
400/// within.
401pub trait FloorPlanner {
402    /// Given the provided `cs`, synthesize the given circuit.
403    ///
404    /// `constants` is the list of fixed columns that the layouter may use to assign
405    /// global constant values. These columns will all have been equality-enabled.
406    ///
407    /// Internally, a floor planner will perform the following operations:
408    /// - Instantiate a [`Layouter`] for this floor planner.
409    /// - Perform any necessary setup or measurement tasks, which may involve one or more
410    ///   calls to `Circuit::default().synthesize(config, &mut layouter)`.
411    /// - Call `circuit.synthesize(config, &mut layouter)` exactly once.
412    fn synthesize<F: Field, CS: Assignment<F>, C: Circuit<F>>(
413        cs: &mut CS,
414        circuit: &C,
415        config: C::Config,
416        constants: Vec<Column<Fixed>>,
417    ) -> Result<(), Error>;
418}
419
420/// This is a trait that circuits provide implementations for so that the
421/// backend prover can ask the circuit to synthesize using some given
422/// [`ConstraintSystem`] implementation.
423pub trait Circuit<F: Field> {
424    /// This is a configuration object that stores things like columns.
425    type Config: Clone;
426    /// The floor planner used for this circuit. This is an associated type of the
427    /// `Circuit` trait because its behaviour is circuit-critical.
428    type FloorPlanner: FloorPlanner;
429
430    /// Returns a copy of this circuit with no witness values (i.e. all witnesses set to
431    /// `None`). For most circuits, this will be equal to `Self::default()`.
432    fn without_witnesses(&self) -> Self;
433
434    /// The circuit is given an opportunity to describe the exact gate
435    /// arrangement, column arrangement, etc.
436    fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config;
437
438    /// Given the provided `cs`, synthesize the circuit. The concrete type of
439    /// the caller will be different depending on the context, and they may or
440    /// may not expect to have a witness present.
441    fn synthesize(&self, config: Self::Config, layouter: impl Layouter<F>) -> Result<(), Error>;
442}
443
444/// Low-degree expression representing an identity that must hold over the committed columns.
445#[derive(Clone, Debug)]
446pub enum Expression<F> {
447    /// This is a constant polynomial
448    Constant(F),
449    /// This is a virtual selector
450    Selector(Selector),
451    /// This is a fixed column queried at a certain relative location
452    Fixed {
453        /// Query index
454        query_index: usize,
455        /// Column index
456        column_index: usize,
457        /// Rotation of this query
458        rotation: Rotation,
459    },
460    /// This is an advice (witness) column queried at a certain relative location
461    Advice {
462        /// Query index
463        query_index: usize,
464        /// Column index
465        column_index: usize,
466        /// Rotation of this query
467        rotation: Rotation,
468    },
469    /// This is an instance (external) column queried at a certain relative location
470    Instance {
471        /// Query index
472        query_index: usize,
473        /// Column index
474        column_index: usize,
475        /// Rotation of this query
476        rotation: Rotation,
477    },
478    /// This is a negated polynomial
479    Negated(Box<Expression<F>>),
480    /// This is the sum of two polynomials
481    Sum(Box<Expression<F>>, Box<Expression<F>>),
482    /// This is the product of two polynomials
483    Product(Box<Expression<F>>, Box<Expression<F>>),
484    /// This is a scaled polynomial
485    Scaled(Box<Expression<F>>, F),
486}
487
488impl<F: Field> Expression<F> {
489    /// Evaluate the polynomial using the provided closures to perform the
490    /// operations.
491    pub fn evaluate<T>(
492        &self,
493        constant: &impl Fn(F) -> T,
494        selector_column: &impl Fn(Selector) -> T,
495        fixed_column: &impl Fn(usize, usize, Rotation) -> T,
496        advice_column: &impl Fn(usize, usize, Rotation) -> T,
497        instance_column: &impl Fn(usize, usize, Rotation) -> T,
498        negated: &impl Fn(T) -> T,
499        sum: &impl Fn(T, T) -> T,
500        product: &impl Fn(T, T) -> T,
501        scaled: &impl Fn(T, F) -> T,
502    ) -> T {
503        match self {
504            Expression::Constant(scalar) => constant(*scalar),
505            Expression::Selector(selector) => selector_column(*selector),
506            Expression::Fixed {
507                query_index,
508                column_index,
509                rotation,
510            } => fixed_column(*query_index, *column_index, *rotation),
511            Expression::Advice {
512                query_index,
513                column_index,
514                rotation,
515            } => advice_column(*query_index, *column_index, *rotation),
516            Expression::Instance {
517                query_index,
518                column_index,
519                rotation,
520            } => instance_column(*query_index, *column_index, *rotation),
521            Expression::Negated(a) => {
522                let a = a.evaluate(
523                    constant,
524                    selector_column,
525                    fixed_column,
526                    advice_column,
527                    instance_column,
528                    negated,
529                    sum,
530                    product,
531                    scaled,
532                );
533                negated(a)
534            }
535            Expression::Sum(a, b) => {
536                let a = a.evaluate(
537                    constant,
538                    selector_column,
539                    fixed_column,
540                    advice_column,
541                    instance_column,
542                    negated,
543                    sum,
544                    product,
545                    scaled,
546                );
547                let b = b.evaluate(
548                    constant,
549                    selector_column,
550                    fixed_column,
551                    advice_column,
552                    instance_column,
553                    negated,
554                    sum,
555                    product,
556                    scaled,
557                );
558                sum(a, b)
559            }
560            Expression::Product(a, b) => {
561                let a = a.evaluate(
562                    constant,
563                    selector_column,
564                    fixed_column,
565                    advice_column,
566                    instance_column,
567                    negated,
568                    sum,
569                    product,
570                    scaled,
571                );
572                let b = b.evaluate(
573                    constant,
574                    selector_column,
575                    fixed_column,
576                    advice_column,
577                    instance_column,
578                    negated,
579                    sum,
580                    product,
581                    scaled,
582                );
583                product(a, b)
584            }
585            Expression::Scaled(a, f) => {
586                let a = a.evaluate(
587                    constant,
588                    selector_column,
589                    fixed_column,
590                    advice_column,
591                    instance_column,
592                    negated,
593                    sum,
594                    product,
595                    scaled,
596                );
597                scaled(a, *f)
598            }
599        }
600    }
601
602    /// Compute the degree of this polynomial
603    pub fn degree(&self) -> usize {
604        match self {
605            Expression::Constant(_) => 0,
606            Expression::Selector(_) => 1,
607            Expression::Fixed { .. } => 1,
608            Expression::Advice { .. } => 1,
609            Expression::Instance { .. } => 1,
610            Expression::Negated(poly) => poly.degree(),
611            Expression::Sum(a, b) => max(a.degree(), b.degree()),
612            Expression::Product(a, b) => a.degree() + b.degree(),
613            Expression::Scaled(poly, _) => poly.degree(),
614        }
615    }
616
617    /// Square this expression.
618    pub fn square(self) -> Self {
619        self.clone() * self
620    }
621
622    /// Returns whether or not this expression contains a simple `Selector`.
623    fn contains_simple_selector(&self) -> bool {
624        self.evaluate(
625            &|_| false,
626            &|selector| selector.is_simple(),
627            &|_, _, _| false,
628            &|_, _, _| false,
629            &|_, _, _| false,
630            &|a| a,
631            &|a, b| a || b,
632            &|a, b| a || b,
633            &|a, _| a,
634        )
635    }
636
637    /// Extracts a simple selector from this gate, if present
638    fn extract_simple_selector(&self) -> Option<Selector> {
639        let op = |a, b| match (a, b) {
640            (Some(a), None) | (None, Some(a)) => Some(a),
641            (Some(_), Some(_)) => panic!("two simple selectors cannot be in the same expression"),
642            _ => None,
643        };
644
645        self.evaluate(
646            &|_| None,
647            &|selector| {
648                if selector.is_simple() {
649                    Some(selector)
650                } else {
651                    None
652                }
653            },
654            &|_, _, _| None,
655            &|_, _, _| None,
656            &|_, _, _| None,
657            &|a| a,
658            &op,
659            &op,
660            &|a, _| a,
661        )
662    }
663}
664
665impl<F: Field> Neg for Expression<F> {
666    type Output = Expression<F>;
667    fn neg(self) -> Self::Output {
668        Expression::Negated(Box::new(self))
669    }
670}
671
672impl<F: Field> Add for Expression<F> {
673    type Output = Expression<F>;
674    fn add(self, rhs: Expression<F>) -> Expression<F> {
675        if self.contains_simple_selector() || rhs.contains_simple_selector() {
676            panic!("attempted to use a simple selector in an addition");
677        }
678        Expression::Sum(Box::new(self), Box::new(rhs))
679    }
680}
681
682impl<F: Field> Sub for Expression<F> {
683    type Output = Expression<F>;
684    fn sub(self, rhs: Expression<F>) -> Expression<F> {
685        if self.contains_simple_selector() || rhs.contains_simple_selector() {
686            panic!("attempted to use a simple selector in a subtraction");
687        }
688        Expression::Sum(Box::new(self), Box::new(-rhs))
689    }
690}
691
692impl<F: Field> Mul for Expression<F> {
693    type Output = Expression<F>;
694    fn mul(self, rhs: Expression<F>) -> Expression<F> {
695        if self.contains_simple_selector() && rhs.contains_simple_selector() {
696            panic!("attempted to multiply two expressions containing simple selectors");
697        }
698        Expression::Product(Box::new(self), Box::new(rhs))
699    }
700}
701
702impl<F: Field> Mul<F> for Expression<F> {
703    type Output = Expression<F>;
704    fn mul(self, rhs: F) -> Expression<F> {
705        Expression::Scaled(Box::new(self), rhs)
706    }
707}
708
709/// Represents an index into a vector where each entry corresponds to a distinct
710/// point that polynomials are queried at.
711#[derive(Copy, Clone, Debug)]
712pub(crate) struct PointIndex(pub usize);
713
714/// A "virtual cell" is a PLONK cell that has been queried at a particular relative offset
715/// within a custom gate.
716#[derive(Clone, Debug)]
717pub(crate) struct VirtualCell {
718    pub(crate) column: Column<Any>,
719    pub(crate) rotation: Rotation,
720}
721
722impl<Col: Into<Column<Any>>> From<(Col, Rotation)> for VirtualCell {
723    fn from((column, rotation): (Col, Rotation)) -> Self {
724        VirtualCell {
725            column: column.into(),
726            rotation,
727        }
728    }
729}
730
731/// An individual polynomial constraint.
732///
733/// These are returned by the closures passed to `ConstraintSystem::create_gate`.
734#[derive(Debug)]
735pub struct Constraint<F: Field> {
736    name: &'static str,
737    poly: Expression<F>,
738}
739
740impl<F: Field> From<Expression<F>> for Constraint<F> {
741    fn from(poly: Expression<F>) -> Self {
742        Constraint { name: "", poly }
743    }
744}
745
746impl<F: Field> From<(&'static str, Expression<F>)> for Constraint<F> {
747    fn from((name, poly): (&'static str, Expression<F>)) -> Self {
748        Constraint { name, poly }
749    }
750}
751
752impl<F: Field> From<Expression<F>> for Vec<Constraint<F>> {
753    fn from(poly: Expression<F>) -> Self {
754        vec![Constraint { name: "", poly }]
755    }
756}
757
758/// A set of polynomial constraints with a common selector.
759///
760/// ```
761/// use halo2_proofs::{pasta::Fp, plonk::{Constraints, Expression}, poly::Rotation};
762/// # use halo2_proofs::plonk::ConstraintSystem;
763///
764/// # let mut meta = ConstraintSystem::<Fp>::default();
765/// let a = meta.advice_column();
766/// let b = meta.advice_column();
767/// let c = meta.advice_column();
768/// let s = meta.selector();
769///
770/// meta.create_gate("foo", |meta| {
771///     let next = meta.query_advice(a, Rotation::next());
772///     let a = meta.query_advice(a, Rotation::cur());
773///     let b = meta.query_advice(b, Rotation::cur());
774///     let c = meta.query_advice(c, Rotation::cur());
775///     let s_ternary = meta.query_selector(s);
776///
777///     let one_minus_a = Expression::Constant(Fp::one()) - a.clone();
778///
779///     Constraints::with_selector(
780///         s_ternary,
781///         std::array::IntoIter::new([
782///             ("a is boolean", a.clone() * one_minus_a.clone()),
783///             ("next == a ? b : c", next - (a * b + one_minus_a * c)),
784///         ]),
785///     )
786/// });
787/// ```
788///
789/// Note that the use of `std::array::IntoIter::new` is only necessary if you need to
790/// support Rust 1.51 or 1.52. If your minimum supported Rust version is 1.53 or greater,
791/// you can pass an array directly.
792#[derive(Debug)]
793pub struct Constraints<F: Field, C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>> {
794    selector: Expression<F>,
795    constraints: Iter,
796}
797
798impl<F: Field, C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>> Constraints<F, C, Iter> {
799    /// Constructs a set of constraints that are controlled by the given selector.
800    ///
801    /// Each constraint `c` in `iterator` will be converted into the constraint
802    /// `selector * c`.
803    pub fn with_selector(selector: Expression<F>, constraints: Iter) -> Self {
804        Constraints {
805            selector,
806            constraints,
807        }
808    }
809}
810
811fn apply_selector_to_constraint<F: Field, C: Into<Constraint<F>>>(
812    (selector, c): (Expression<F>, C),
813) -> Constraint<F> {
814    let constraint: Constraint<F> = c.into();
815    Constraint {
816        name: constraint.name,
817        poly: selector * constraint.poly,
818    }
819}
820
821type ApplySelectorToConstraint<F, C> = fn((Expression<F>, C)) -> Constraint<F>;
822type ConstraintsIterator<F, C, I> = std::iter::Map<
823    std::iter::Zip<std::iter::Repeat<Expression<F>>, I>,
824    ApplySelectorToConstraint<F, C>,
825>;
826
827impl<F: Field, C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>> IntoIterator
828    for Constraints<F, C, Iter>
829{
830    type Item = Constraint<F>;
831    type IntoIter = ConstraintsIterator<F, C, Iter::IntoIter>;
832
833    fn into_iter(self) -> Self::IntoIter {
834        std::iter::repeat(self.selector)
835            .zip(self.constraints.into_iter())
836            .map(apply_selector_to_constraint)
837    }
838}
839
840#[derive(Clone, Debug)]
841pub(crate) struct Gate<F: Field> {
842    name: &'static str,
843    constraint_names: Vec<&'static str>,
844    polys: Vec<Expression<F>>,
845    /// We track queried selectors separately from other cells, so that we can use them to
846    /// trigger debug checks on gates.
847    queried_selectors: Vec<Selector>,
848    queried_cells: Vec<VirtualCell>,
849}
850
851impl<F: Field> Gate<F> {
852    pub(crate) fn name(&self) -> &'static str {
853        self.name
854    }
855
856    pub(crate) fn constraint_name(&self, constraint_index: usize) -> &'static str {
857        self.constraint_names[constraint_index]
858    }
859
860    pub(crate) fn polynomials(&self) -> &[Expression<F>] {
861        &self.polys
862    }
863
864    pub(crate) fn queried_selectors(&self) -> &[Selector] {
865        &self.queried_selectors
866    }
867
868    pub(crate) fn queried_cells(&self) -> &[VirtualCell] {
869        &self.queried_cells
870    }
871}
872
873/// This is a description of the circuit environment, such as the gate, column and
874/// permutation arrangements.
875#[derive(Debug, Clone)]
876pub struct ConstraintSystem<F: Field> {
877    pub(crate) num_fixed_columns: usize,
878    pub(crate) num_advice_columns: usize,
879    pub(crate) num_instance_columns: usize,
880    pub(crate) num_selectors: usize,
881
882    /// This is a cached vector that maps virtual selectors to the concrete
883    /// fixed column that they were compressed into. This is just used by dev
884    /// tooling right now.
885    pub(crate) selector_map: Vec<Column<Fixed>>,
886
887    pub(crate) gates: Vec<Gate<F>>,
888    pub(crate) advice_queries: Vec<(Column<Advice>, Rotation)>,
889    // Contains an integer for each advice column
890    // identifying how many distinct queries it has
891    // so far; should be same length as num_advice_columns.
892    num_advice_queries: Vec<usize>,
893    pub(crate) instance_queries: Vec<(Column<Instance>, Rotation)>,
894    pub(crate) fixed_queries: Vec<(Column<Fixed>, Rotation)>,
895
896    // Permutation argument for performing equality constraints
897    pub(crate) permutation: permutation::Argument,
898
899    // Vector of lookup arguments, where each corresponds to a sequence of
900    // input expressions and a sequence of table expressions involved in the lookup.
901    pub(crate) lookups: Vec<lookup::Argument<F>>,
902
903    // Vector of fixed columns, which can be used to store constant values
904    // that are copied into advice columns.
905    pub(crate) constants: Vec<Column<Fixed>>,
906
907    pub(crate) minimum_degree: Option<usize>,
908}
909
910/// Represents the minimal parameters that determine a `ConstraintSystem`.
911#[allow(dead_code)]
912#[derive(Debug)]
913pub struct PinnedConstraintSystem<'a, F: Field> {
914    num_fixed_columns: &'a usize,
915    num_advice_columns: &'a usize,
916    num_instance_columns: &'a usize,
917    num_selectors: &'a usize,
918    gates: PinnedGates<'a, F>,
919    advice_queries: &'a Vec<(Column<Advice>, Rotation)>,
920    instance_queries: &'a Vec<(Column<Instance>, Rotation)>,
921    fixed_queries: &'a Vec<(Column<Fixed>, Rotation)>,
922    permutation: &'a permutation::Argument,
923    lookups: &'a Vec<lookup::Argument<F>>,
924    constants: &'a Vec<Column<Fixed>>,
925    minimum_degree: &'a Option<usize>,
926}
927
928struct PinnedGates<'a, F: Field>(&'a Vec<Gate<F>>);
929
930impl<'a, F: Field> std::fmt::Debug for PinnedGates<'a, F> {
931    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
932        f.debug_list()
933            .entries(self.0.iter().flat_map(|gate| gate.polynomials().iter()))
934            .finish()
935    }
936}
937
938impl<F: Field> Default for ConstraintSystem<F> {
939    fn default() -> ConstraintSystem<F> {
940        ConstraintSystem {
941            num_fixed_columns: 0,
942            num_advice_columns: 0,
943            num_instance_columns: 0,
944            num_selectors: 0,
945            selector_map: vec![],
946            gates: vec![],
947            fixed_queries: Vec::new(),
948            advice_queries: Vec::new(),
949            num_advice_queries: Vec::new(),
950            instance_queries: Vec::new(),
951            permutation: permutation::Argument::new(),
952            lookups: Vec::new(),
953            constants: vec![],
954            minimum_degree: None,
955        }
956    }
957}
958
959impl<F: Field> ConstraintSystem<F> {
960    /// Obtain a pinned version of this constraint system; a structure with the
961    /// minimal parameters needed to determine the rest of the constraint
962    /// system.
963    pub fn pinned(&self) -> PinnedConstraintSystem<'_, F> {
964        PinnedConstraintSystem {
965            num_fixed_columns: &self.num_fixed_columns,
966            num_advice_columns: &self.num_advice_columns,
967            num_instance_columns: &self.num_instance_columns,
968            num_selectors: &self.num_selectors,
969            gates: PinnedGates(&self.gates),
970            fixed_queries: &self.fixed_queries,
971            advice_queries: &self.advice_queries,
972            instance_queries: &self.instance_queries,
973            permutation: &self.permutation,
974            lookups: &self.lookups,
975            constants: &self.constants,
976            minimum_degree: &self.minimum_degree,
977        }
978    }
979
980    /// Enables this fixed column to be used for global constant assignments.
981    ///
982    /// # Side-effects
983    ///
984    /// The column will be equality-enabled.
985    pub fn enable_constant(&mut self, column: Column<Fixed>) {
986        if !self.constants.contains(&column) {
987            self.constants.push(column);
988            self.enable_equality(column);
989        }
990    }
991
992    /// Enable the ability to enforce equality over cells in this column
993    pub fn enable_equality<C: Into<Column<Any>>>(&mut self, column: C) {
994        let column = column.into();
995        self.query_any_index(column, Rotation::cur());
996        self.permutation.add_column(column);
997    }
998
999    /// Add a lookup argument for some input expressions and table columns.
1000    ///
1001    /// `table_map` returns a map between input expressions and the table columns
1002    /// they need to match.
1003    pub fn lookup(
1004        &mut self,
1005        table_map: impl FnOnce(&mut VirtualCells<'_, F>) -> Vec<(Expression<F>, TableColumn)>,
1006    ) -> usize {
1007        let mut cells = VirtualCells::new(self);
1008        let table_map = table_map(&mut cells)
1009            .into_iter()
1010            .map(|(input, table)| {
1011                if input.contains_simple_selector() {
1012                    panic!("expression containing simple selector supplied to lookup argument");
1013                }
1014
1015                let table = cells.query_fixed(table.inner(), Rotation::cur());
1016
1017                (input, table)
1018            })
1019            .collect();
1020
1021        let index = self.lookups.len();
1022
1023        self.lookups.push(lookup::Argument::new(table_map));
1024
1025        index
1026    }
1027
1028    fn query_fixed_index(&mut self, column: Column<Fixed>, at: Rotation) -> usize {
1029        // Return existing query, if it exists
1030        for (index, fixed_query) in self.fixed_queries.iter().enumerate() {
1031            if fixed_query == &(column, at) {
1032                return index;
1033            }
1034        }
1035
1036        // Make a new query
1037        let index = self.fixed_queries.len();
1038        self.fixed_queries.push((column, at));
1039
1040        index
1041    }
1042
1043    pub(crate) fn query_advice_index(&mut self, column: Column<Advice>, at: Rotation) -> usize {
1044        // Return existing query, if it exists
1045        for (index, advice_query) in self.advice_queries.iter().enumerate() {
1046            if advice_query == &(column, at) {
1047                return index;
1048            }
1049        }
1050
1051        // Make a new query
1052        let index = self.advice_queries.len();
1053        self.advice_queries.push((column, at));
1054        self.num_advice_queries[column.index] += 1;
1055
1056        index
1057    }
1058
1059    fn query_instance_index(&mut self, column: Column<Instance>, at: Rotation) -> usize {
1060        // Return existing query, if it exists
1061        for (index, instance_query) in self.instance_queries.iter().enumerate() {
1062            if instance_query == &(column, at) {
1063                return index;
1064            }
1065        }
1066
1067        // Make a new query
1068        let index = self.instance_queries.len();
1069        self.instance_queries.push((column, at));
1070
1071        index
1072    }
1073
1074    fn query_any_index(&mut self, column: Column<Any>, at: Rotation) -> usize {
1075        match column.column_type() {
1076            Any::Advice => self.query_advice_index(Column::<Advice>::try_from(column).unwrap(), at),
1077            Any::Fixed => self.query_fixed_index(Column::<Fixed>::try_from(column).unwrap(), at),
1078            Any::Instance => {
1079                self.query_instance_index(Column::<Instance>::try_from(column).unwrap(), at)
1080            }
1081        }
1082    }
1083
1084    pub(crate) fn get_advice_query_index(&self, column: Column<Advice>, at: Rotation) -> usize {
1085        for (index, advice_query) in self.advice_queries.iter().enumerate() {
1086            if advice_query == &(column, at) {
1087                return index;
1088            }
1089        }
1090
1091        panic!("get_advice_query_index called for non-existent query");
1092    }
1093
1094    pub(crate) fn get_fixed_query_index(&self, column: Column<Fixed>, at: Rotation) -> usize {
1095        for (index, fixed_query) in self.fixed_queries.iter().enumerate() {
1096            if fixed_query == &(column, at) {
1097                return index;
1098            }
1099        }
1100
1101        panic!("get_fixed_query_index called for non-existent query");
1102    }
1103
1104    pub(crate) fn get_instance_query_index(&self, column: Column<Instance>, at: Rotation) -> usize {
1105        for (index, instance_query) in self.instance_queries.iter().enumerate() {
1106            if instance_query == &(column, at) {
1107                return index;
1108            }
1109        }
1110
1111        panic!("get_instance_query_index called for non-existent query");
1112    }
1113
1114    pub(crate) fn get_any_query_index(&self, column: Column<Any>, at: Rotation) -> usize {
1115        match column.column_type() {
1116            Any::Advice => {
1117                self.get_advice_query_index(Column::<Advice>::try_from(column).unwrap(), at)
1118            }
1119            Any::Fixed => {
1120                self.get_fixed_query_index(Column::<Fixed>::try_from(column).unwrap(), at)
1121            }
1122            Any::Instance => {
1123                self.get_instance_query_index(Column::<Instance>::try_from(column).unwrap(), at)
1124            }
1125        }
1126    }
1127
1128    /// Sets the minimum degree required by the circuit, which can be set to a
1129    /// larger amount than actually needed. This can be used, for example, to
1130    /// force the permutation argument to involve more columns in the same set.
1131    pub fn set_minimum_degree(&mut self, degree: usize) {
1132        self.minimum_degree = Some(degree);
1133    }
1134
1135    /// Creates a new gate.
1136    ///
1137    /// # Panics
1138    ///
1139    /// A gate is required to contain polynomial constraints. This method will panic if
1140    /// `constraints` returns an empty iterator.
1141    pub fn create_gate<C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>>(
1142        &mut self,
1143        name: &'static str,
1144        constraints: impl FnOnce(&mut VirtualCells<'_, F>) -> Iter,
1145    ) {
1146        let mut cells = VirtualCells::new(self);
1147        let constraints = constraints(&mut cells);
1148        let queried_selectors = cells.queried_selectors;
1149        let queried_cells = cells.queried_cells;
1150
1151        let (constraint_names, polys): (_, Vec<_>) = constraints
1152            .into_iter()
1153            .map(|c| c.into())
1154            .map(|c| (c.name, c.poly))
1155            .unzip();
1156
1157        assert!(
1158            !polys.is_empty(),
1159            "Gates must contain at least one constraint."
1160        );
1161
1162        self.gates.push(Gate {
1163            name,
1164            constraint_names,
1165            polys,
1166            queried_selectors,
1167            queried_cells,
1168        });
1169    }
1170
1171    /// This will compress selectors together depending on their provided
1172    /// assignments. This `ConstraintSystem` will then be modified to add new
1173    /// fixed columns (representing the actual selectors) and will return the
1174    /// polynomials for those columns. Finally, an internal map is updated to
1175    /// find which fixed column corresponds with a given `Selector`.
1176    ///
1177    /// Do not call this twice. Yes, this should be a builder pattern instead.
1178    pub(crate) fn compress_selectors(mut self, selectors: Vec<Vec<bool>>) -> (Self, Vec<Vec<F>>) {
1179        // The number of provided selector assignments must be the number we
1180        // counted for this constraint system.
1181        assert_eq!(selectors.len(), self.num_selectors);
1182
1183        // Compute the maximal degree of every selector. We only consider the
1184        // expressions in gates, as lookup arguments cannot support simple
1185        // selectors. Selectors that are complex or do not appear in any gates
1186        // will have degree zero.
1187        let mut degrees = vec![0; selectors.len()];
1188        for expr in self.gates.iter().flat_map(|gate| gate.polys.iter()) {
1189            if let Some(selector) = expr.extract_simple_selector() {
1190                degrees[selector.0] = max(degrees[selector.0], expr.degree());
1191            }
1192        }
1193
1194        // We will not increase the degree of the constraint system, so we limit
1195        // ourselves to the largest existing degree constraint.
1196        let max_degree = self.degree();
1197
1198        let mut new_columns = vec![];
1199        let (polys, selector_assignment) = compress_selectors::process(
1200            selectors
1201                .into_iter()
1202                .zip(degrees.into_iter())
1203                .enumerate()
1204                .map(
1205                    |(i, (activations, max_degree))| compress_selectors::SelectorDescription {
1206                        selector: i,
1207                        activations,
1208                        max_degree,
1209                    },
1210                )
1211                .collect(),
1212            max_degree,
1213            || {
1214                let column = self.fixed_column();
1215                new_columns.push(column);
1216                Expression::Fixed {
1217                    query_index: self.query_fixed_index(column, Rotation::cur()),
1218                    column_index: column.index,
1219                    rotation: Rotation::cur(),
1220                }
1221            },
1222        );
1223
1224        let mut selector_map = vec![None; selector_assignment.len()];
1225        let mut selector_replacements = vec![None; selector_assignment.len()];
1226        for assignment in selector_assignment {
1227            selector_replacements[assignment.selector] = Some(assignment.expression);
1228            selector_map[assignment.selector] = Some(new_columns[assignment.combination_index]);
1229        }
1230
1231        self.selector_map = selector_map
1232            .into_iter()
1233            .map(|a| a.unwrap())
1234            .collect::<Vec<_>>();
1235        let selector_replacements = selector_replacements
1236            .into_iter()
1237            .map(|a| a.unwrap())
1238            .collect::<Vec<_>>();
1239
1240        fn replace_selectors<F: Field>(
1241            expr: &mut Expression<F>,
1242            selector_replacements: &[Expression<F>],
1243            must_be_nonsimple: bool,
1244        ) {
1245            *expr = expr.evaluate(
1246                &|constant| Expression::Constant(constant),
1247                &|selector| {
1248                    if must_be_nonsimple {
1249                        // Simple selectors are prohibited from appearing in
1250                        // expressions in the lookup argument by
1251                        // `ConstraintSystem`.
1252                        assert!(!selector.is_simple());
1253                    }
1254
1255                    selector_replacements[selector.0].clone()
1256                },
1257                &|query_index, column_index, rotation| Expression::Fixed {
1258                    query_index,
1259                    column_index,
1260                    rotation,
1261                },
1262                &|query_index, column_index, rotation| Expression::Advice {
1263                    query_index,
1264                    column_index,
1265                    rotation,
1266                },
1267                &|query_index, column_index, rotation| Expression::Instance {
1268                    query_index,
1269                    column_index,
1270                    rotation,
1271                },
1272                &|a| -a,
1273                &|a, b| a + b,
1274                &|a, b| a * b,
1275                &|a, f| a * f,
1276            );
1277        }
1278
1279        // Substitute selectors for the real fixed columns in all gates
1280        for expr in self.gates.iter_mut().flat_map(|gate| gate.polys.iter_mut()) {
1281            replace_selectors(expr, &selector_replacements, false);
1282        }
1283
1284        // Substitute non-simple selectors for the real fixed columns in all
1285        // lookup expressions
1286        for expr in self.lookups.iter_mut().flat_map(|lookup| {
1287            lookup
1288                .input_expressions
1289                .iter_mut()
1290                .chain(lookup.table_expressions.iter_mut())
1291        }) {
1292            replace_selectors(expr, &selector_replacements, true);
1293        }
1294
1295        (self, polys)
1296    }
1297
1298    /// Allocate a new (simple) selector. Simple selectors cannot be added to
1299    /// expressions nor multiplied by other expressions containing simple
1300    /// selectors. Also, simple selectors may not appear in lookup argument
1301    /// inputs.
1302    pub fn selector(&mut self) -> Selector {
1303        let index = self.num_selectors;
1304        self.num_selectors += 1;
1305        Selector(index, true)
1306    }
1307
1308    /// Allocate a new complex selector that can appear anywhere
1309    /// within expressions.
1310    pub fn complex_selector(&mut self) -> Selector {
1311        let index = self.num_selectors;
1312        self.num_selectors += 1;
1313        Selector(index, false)
1314    }
1315
1316    /// Allocates a new fixed column that can be used in a lookup table.
1317    pub fn lookup_table_column(&mut self) -> TableColumn {
1318        TableColumn {
1319            inner: self.fixed_column(),
1320        }
1321    }
1322
1323    /// Allocate a new fixed column
1324    pub fn fixed_column(&mut self) -> Column<Fixed> {
1325        let tmp = Column {
1326            index: self.num_fixed_columns,
1327            column_type: Fixed,
1328        };
1329        self.num_fixed_columns += 1;
1330        tmp
1331    }
1332
1333    /// Allocate a new advice column
1334    pub fn advice_column(&mut self) -> Column<Advice> {
1335        let tmp = Column {
1336            index: self.num_advice_columns,
1337            column_type: Advice,
1338        };
1339        self.num_advice_columns += 1;
1340        self.num_advice_queries.push(0);
1341        tmp
1342    }
1343
1344    /// Allocate a new instance column
1345    pub fn instance_column(&mut self) -> Column<Instance> {
1346        let tmp = Column {
1347            index: self.num_instance_columns,
1348            column_type: Instance,
1349        };
1350        self.num_instance_columns += 1;
1351        tmp
1352    }
1353
1354    /// Compute the degree of the constraint system (the maximum degree of all
1355    /// constraints).
1356    pub fn degree(&self) -> usize {
1357        // The permutation argument will serve alongside the gates, so must be
1358        // accounted for.
1359        let mut degree = self.permutation.required_degree();
1360
1361        // The lookup argument also serves alongside the gates and must be accounted
1362        // for.
1363        degree = std::cmp::max(
1364            degree,
1365            self.lookups
1366                .iter()
1367                .map(|l| l.required_degree())
1368                .max()
1369                .unwrap_or(1),
1370        );
1371
1372        // Account for each gate to ensure our quotient polynomial is the
1373        // correct degree and that our extended domain is the right size.
1374        degree = std::cmp::max(
1375            degree,
1376            self.gates
1377                .iter()
1378                .flat_map(|gate| gate.polynomials().iter().map(|poly| poly.degree()))
1379                .max()
1380                .unwrap_or(0),
1381        );
1382
1383        std::cmp::max(degree, self.minimum_degree.unwrap_or(1))
1384    }
1385
1386    /// Compute the number of blinding factors necessary to perfectly blind
1387    /// each of the prover's witness polynomials.
1388    pub fn blinding_factors(&self) -> usize {
1389        // All of the prover's advice columns are evaluated at no more than
1390        let factors = *self.num_advice_queries.iter().max().unwrap_or(&1);
1391        // distinct points during gate checks.
1392
1393        // - The permutation argument witness polynomials are evaluated at most 3 times.
1394        // - Each lookup argument has independent witness polynomials, and they are
1395        //   evaluated at most 2 times.
1396        let factors = std::cmp::max(3, factors);
1397
1398        // Each polynomial is evaluated at most an additional time during
1399        // multiopen (at x_3 to produce q_evals):
1400        let factors = factors + 1;
1401
1402        // h(x) is derived by the other evaluations so it does not reveal
1403        // anything; in fact it does not even appear in the proof.
1404
1405        // h(x_3) is also not revealed; the verifier only learns a single
1406        // evaluation of a polynomial in x_1 which has h(x_3) and another random
1407        // polynomial evaluated at x_3 as coefficients -- this random polynomial
1408        // is "random_poly" in the vanishing argument.
1409
1410        // Add an additional blinding factor as a slight defense against
1411        // off-by-one errors.
1412        factors + 1
1413    }
1414
1415    /// Returns the minimum necessary rows that need to exist in order to
1416    /// account for e.g. blinding factors.
1417    pub fn minimum_rows(&self) -> usize {
1418        self.blinding_factors() // m blinding factors
1419            + 1 // for l_{-(m + 1)} (l_last)
1420            + 1 // for l_0 (just for extra breathing room for the permutation
1421                // argument, to essentially force a separation in the
1422                // permutation polynomial between the roles of l_last, l_0
1423                // and the interstitial values.)
1424            + 1 // for at least one row
1425    }
1426}
1427
1428/// Exposes the "virtual cells" that can be queried while creating a custom gate or lookup
1429/// table.
1430#[derive(Debug)]
1431pub struct VirtualCells<'a, F: Field> {
1432    meta: &'a mut ConstraintSystem<F>,
1433    queried_selectors: Vec<Selector>,
1434    queried_cells: Vec<VirtualCell>,
1435}
1436
1437impl<'a, F: Field> VirtualCells<'a, F> {
1438    fn new(meta: &'a mut ConstraintSystem<F>) -> Self {
1439        VirtualCells {
1440            meta,
1441            queried_selectors: vec![],
1442            queried_cells: vec![],
1443        }
1444    }
1445
1446    /// Query a selector at the current position.
1447    pub fn query_selector(&mut self, selector: Selector) -> Expression<F> {
1448        self.queried_selectors.push(selector);
1449        Expression::Selector(selector)
1450    }
1451
1452    /// Query a fixed column at a relative position
1453    pub fn query_fixed(&mut self, column: Column<Fixed>, at: Rotation) -> Expression<F> {
1454        self.queried_cells.push((column, at).into());
1455        Expression::Fixed {
1456            query_index: self.meta.query_fixed_index(column, at),
1457            column_index: column.index,
1458            rotation: at,
1459        }
1460    }
1461
1462    /// Query an advice column at a relative position
1463    pub fn query_advice(&mut self, column: Column<Advice>, at: Rotation) -> Expression<F> {
1464        self.queried_cells.push((column, at).into());
1465        Expression::Advice {
1466            query_index: self.meta.query_advice_index(column, at),
1467            column_index: column.index,
1468            rotation: at,
1469        }
1470    }
1471
1472    /// Query an instance column at a relative position
1473    pub fn query_instance(&mut self, column: Column<Instance>, at: Rotation) -> Expression<F> {
1474        self.queried_cells.push((column, at).into());
1475        Expression::Instance {
1476            query_index: self.meta.query_instance_index(column, at),
1477            column_index: column.index,
1478            rotation: at,
1479        }
1480    }
1481
1482    /// Query an Any column at a relative position
1483    pub fn query_any<C: Into<Column<Any>>>(&mut self, column: C, at: Rotation) -> Expression<F> {
1484        let column = column.into();
1485        match column.column_type() {
1486            Any::Advice => self.query_advice(Column::<Advice>::try_from(column).unwrap(), at),
1487            Any::Fixed => self.query_fixed(Column::<Fixed>::try_from(column).unwrap(), at),
1488            Any::Instance => self.query_instance(Column::<Instance>::try_from(column).unwrap(), at),
1489        }
1490    }
1491}