halo2_axiom/plonk/
circuit.rs

1use super::{lookup, permutation, Assigned, Error};
2use crate::circuit::layouter::SyncDeps;
3use crate::dev::metadata;
4use crate::{
5    circuit::{Layouter, Region, Value},
6    poly::Rotation,
7};
8use core::cmp::max;
9use core::ops::{Add, Mul};
10use ff::Field;
11use itertools::Itertools;
12use sealed::SealedPhase;
13use std::collections::HashMap;
14use std::env::var;
15use std::fmt::Debug;
16use std::{
17    convert::TryFrom,
18    ops::{Neg, Sub},
19};
20
21mod compress_selectors;
22
23/// A column type
24pub trait ColumnType:
25    'static + Sized + Copy + std::fmt::Debug + PartialEq + Eq + Into<Any>
26{
27    /// Return expression from cell
28    fn query_cell<F: Field>(&self, index: usize, at: Rotation) -> Expression<F>;
29}
30
31/// A column with an index and type
32#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
33pub struct Column<C: ColumnType> {
34    index: usize,
35    column_type: C,
36}
37
38impl<C: ColumnType> Column<C> {
39    #[cfg(test)]
40    pub fn new(index: usize, column_type: C) -> Self {
41        Column { index, column_type }
42    }
43
44    /// Index of this column.
45    pub fn index(&self) -> usize {
46        self.index
47    }
48
49    /// Type of this column.
50    pub fn column_type(&self) -> &C {
51        &self.column_type
52    }
53
54    /// Return expression from column at a relative position
55    pub fn query_cell<F: Field>(&self, at: Rotation) -> Expression<F> {
56        self.column_type.query_cell(self.index, at)
57    }
58
59    /// Return expression from column at the current row
60    pub fn cur<F: Field>(&self) -> Expression<F> {
61        self.query_cell(Rotation::cur())
62    }
63
64    /// Return expression from column at the next row
65    pub fn next<F: Field>(&self) -> Expression<F> {
66        self.query_cell(Rotation::next())
67    }
68
69    /// Return expression from column at the previous row
70    pub fn prev<F: Field>(&self) -> Expression<F> {
71        self.query_cell(Rotation::prev())
72    }
73
74    /// Return expression from column at the specified rotation
75    pub fn rot<F: Field>(&self, rotation: i32) -> Expression<F> {
76        self.query_cell(Rotation(rotation))
77    }
78}
79
80impl<C: ColumnType> Ord for Column<C> {
81    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
82        // This ordering is consensus-critical! The layouters rely on deterministic column
83        // orderings.
84        match self.column_type.into().cmp(&other.column_type.into()) {
85            // Indices are assigned within column types.
86            std::cmp::Ordering::Equal => self.index.cmp(&other.index),
87            order => order,
88        }
89    }
90}
91
92impl<C: ColumnType> PartialOrd for Column<C> {
93    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
94        Some(self.cmp(other))
95    }
96}
97
98pub(crate) mod sealed {
99
100    /// Phase of advice column
101    #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
102    pub struct Phase(pub(super) u8);
103
104    impl Phase {
105        pub fn prev(&self) -> Option<Phase> {
106            self.0.checked_sub(1).map(Phase)
107        }
108        pub fn next(&self) -> Phase {
109            assert!(self.0 < 2, "The API only supports three phases");
110            Phase(self.0 + 1)
111        }
112        #[allow(clippy::wrong_self_convention)]
113        pub fn to_u8(&self) -> u8 {
114            self.0
115        }
116    }
117
118    impl SealedPhase for Phase {
119        fn to_sealed(self) -> Phase {
120            self
121        }
122    }
123
124    /// Sealed trait to help keep `Phase` private.
125    pub trait SealedPhase {
126        fn to_sealed(self) -> Phase;
127    }
128}
129
130/// Phase of advice column
131pub trait Phase: SealedPhase {}
132
133impl<P: SealedPhase> Phase for P {}
134
135/// First phase
136#[derive(Debug)]
137pub struct FirstPhase;
138
139impl SealedPhase for super::FirstPhase {
140    fn to_sealed(self) -> sealed::Phase {
141        sealed::Phase(0)
142    }
143}
144
145/// Second phase
146#[derive(Debug)]
147pub struct SecondPhase;
148
149impl SealedPhase for super::SecondPhase {
150    fn to_sealed(self) -> sealed::Phase {
151        sealed::Phase(1)
152    }
153}
154
155/// Third phase
156#[derive(Debug)]
157pub struct ThirdPhase;
158
159impl SealedPhase for super::ThirdPhase {
160    fn to_sealed(self) -> sealed::Phase {
161        sealed::Phase(2)
162    }
163}
164
165/// An advice column
166#[derive(Clone, Copy, Eq, PartialEq, Hash)]
167pub struct Advice {
168    pub(crate) phase: sealed::Phase,
169}
170
171impl Default for Advice {
172    fn default() -> Advice {
173        Advice {
174            phase: FirstPhase.to_sealed(),
175        }
176    }
177}
178
179impl Advice {
180    /// Returns `Advice` in given `Phase`
181    pub fn new<P: Phase>(phase: P) -> Advice {
182        Advice {
183            phase: phase.to_sealed(),
184        }
185    }
186
187    /// Phase of this column
188    pub fn phase(&self) -> u8 {
189        self.phase.0
190    }
191}
192
193impl std::fmt::Debug for Advice {
194    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
195        let mut debug_struct = f.debug_struct("Advice");
196        // Only show advice's phase if it's not in first phase.
197        if self.phase != FirstPhase.to_sealed() {
198            debug_struct.field("phase", &self.phase);
199        }
200        debug_struct.finish()
201    }
202}
203
204/// A fixed column
205#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
206pub struct Fixed;
207
208/// An instance column
209#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
210pub struct Instance;
211
212/// An enum over the Advice, Fixed, Instance structs
213#[derive(Clone, Copy, Eq, PartialEq, Hash)]
214pub enum Any {
215    /// An Advice variant
216    Advice(Advice),
217    /// A Fixed variant
218    Fixed,
219    /// An Instance variant
220    Instance,
221}
222
223impl Any {
224    /// Returns Advice variant in `FirstPhase`
225    pub fn advice() -> Any {
226        Any::Advice(Advice::default())
227    }
228
229    /// Returns Advice variant in given `Phase`
230    pub fn advice_in<P: Phase>(phase: P) -> Any {
231        Any::Advice(Advice::new(phase))
232    }
233}
234
235impl std::fmt::Debug for Any {
236    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237        match self {
238            Any::Advice(advice) => {
239                let mut debug_struct = f.debug_struct("Advice");
240                // Only show advice's phase if it's not in first phase.
241                if advice.phase != FirstPhase.to_sealed() {
242                    debug_struct.field("phase", &advice.phase);
243                }
244                debug_struct.finish()
245            }
246            Any::Fixed => f.debug_struct("Fixed").finish(),
247            Any::Instance => f.debug_struct("Instance").finish(),
248        }
249    }
250}
251
252impl Ord for Any {
253    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
254        // This ordering is consensus-critical! The layouters rely on deterministic column
255        // orderings.
256        match (self, other) {
257            (Any::Instance, Any::Instance) | (Any::Fixed, Any::Fixed) => std::cmp::Ordering::Equal,
258            (Any::Advice(lhs), Any::Advice(rhs)) => lhs.phase.cmp(&rhs.phase),
259            // Across column types, sort Instance < Advice < Fixed.
260            (Any::Instance, Any::Advice(_))
261            | (Any::Advice(_), Any::Fixed)
262            | (Any::Instance, Any::Fixed) => std::cmp::Ordering::Less,
263            (Any::Fixed, Any::Instance)
264            | (Any::Fixed, Any::Advice(_))
265            | (Any::Advice(_), Any::Instance) => std::cmp::Ordering::Greater,
266        }
267    }
268}
269
270impl PartialOrd for Any {
271    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
272        Some(self.cmp(other))
273    }
274}
275
276impl ColumnType for Advice {
277    fn query_cell<F: Field>(&self, index: usize, at: Rotation) -> Expression<F> {
278        Expression::Advice(AdviceQuery {
279            index: None,
280            column_index: index,
281            rotation: at,
282            phase: self.phase,
283        })
284    }
285}
286impl ColumnType for Fixed {
287    fn query_cell<F: Field>(&self, index: usize, at: Rotation) -> Expression<F> {
288        Expression::Fixed(FixedQuery {
289            index: None,
290            column_index: index,
291            rotation: at,
292        })
293    }
294}
295impl ColumnType for Instance {
296    fn query_cell<F: Field>(&self, index: usize, at: Rotation) -> Expression<F> {
297        Expression::Instance(InstanceQuery {
298            index: None,
299            column_index: index,
300            rotation: at,
301        })
302    }
303}
304impl ColumnType for Any {
305    fn query_cell<F: Field>(&self, index: usize, at: Rotation) -> Expression<F> {
306        match self {
307            Any::Advice(Advice { phase }) => Expression::Advice(AdviceQuery {
308                index: None,
309                column_index: index,
310                rotation: at,
311                phase: *phase,
312            }),
313            Any::Fixed => Expression::Fixed(FixedQuery {
314                index: None,
315                column_index: index,
316                rotation: at,
317            }),
318            Any::Instance => Expression::Instance(InstanceQuery {
319                index: None,
320                column_index: index,
321                rotation: at,
322            }),
323        }
324    }
325}
326
327impl From<Advice> for Any {
328    fn from(advice: Advice) -> Any {
329        Any::Advice(advice)
330    }
331}
332
333impl From<Fixed> for Any {
334    fn from(_: Fixed) -> Any {
335        Any::Fixed
336    }
337}
338
339impl From<Instance> for Any {
340    fn from(_: Instance) -> Any {
341        Any::Instance
342    }
343}
344
345impl From<Column<Advice>> for Column<Any> {
346    fn from(advice: Column<Advice>) -> Column<Any> {
347        Column {
348            index: advice.index(),
349            column_type: Any::Advice(advice.column_type),
350        }
351    }
352}
353
354impl From<Column<Fixed>> for Column<Any> {
355    fn from(advice: Column<Fixed>) -> Column<Any> {
356        Column {
357            index: advice.index(),
358            column_type: Any::Fixed,
359        }
360    }
361}
362
363impl From<Column<Instance>> for Column<Any> {
364    fn from(advice: Column<Instance>) -> Column<Any> {
365        Column {
366            index: advice.index(),
367            column_type: Any::Instance,
368        }
369    }
370}
371
372impl TryFrom<Column<Any>> for Column<Advice> {
373    type Error = &'static str;
374
375    fn try_from(any: Column<Any>) -> Result<Self, Self::Error> {
376        match any.column_type() {
377            Any::Advice(advice) => Ok(Column {
378                index: any.index(),
379                column_type: *advice,
380            }),
381            _ => Err("Cannot convert into Column<Advice>"),
382        }
383    }
384}
385
386impl TryFrom<Column<Any>> for Column<Fixed> {
387    type Error = &'static str;
388
389    fn try_from(any: Column<Any>) -> Result<Self, Self::Error> {
390        match any.column_type() {
391            Any::Fixed => Ok(Column {
392                index: any.index(),
393                column_type: Fixed,
394            }),
395            _ => Err("Cannot convert into Column<Fixed>"),
396        }
397    }
398}
399
400impl TryFrom<Column<Any>> for Column<Instance> {
401    type Error = &'static str;
402
403    fn try_from(any: Column<Any>) -> Result<Self, Self::Error> {
404        match any.column_type() {
405            Any::Instance => Ok(Column {
406                index: any.index(),
407                column_type: Instance,
408            }),
409            _ => Err("Cannot convert into Column<Instance>"),
410        }
411    }
412}
413
414/// A selector, representing a fixed boolean value per row of the circuit.
415///
416/// Selectors can be used to conditionally enable (portions of) gates:
417/// ```
418/// use halo2_axiom::poly::Rotation;
419/// # use halo2curves::pasta::Fp;
420/// # use halo2_axiom::plonk::ConstraintSystem;
421///
422/// # let mut meta = ConstraintSystem::<Fp>::default();
423/// let a = meta.advice_column();
424/// let b = meta.advice_column();
425/// let s = meta.selector();
426///
427/// meta.create_gate("foo", |meta| {
428///     let a = meta.query_advice(a, Rotation::prev());
429///     let b = meta.query_advice(b, Rotation::cur());
430///     let s = meta.query_selector(s);
431///
432///     // On rows where the selector is enabled, a is constrained to equal b.
433///     // On rows where the selector is disabled, a and b can take any value.
434///     vec![s * (a - b)]
435/// });
436/// ```
437///
438/// Selectors are disabled on all rows by default, and must be explicitly enabled on each
439/// row when required:
440/// ```
441/// use halo2_axiom::{
442///     circuit::{Chip, Layouter, Value},
443///     plonk::{Advice, Column, Error, Selector},
444/// };
445/// use ff::Field;
446/// # use halo2_axiom::plonk::Fixed;
447///
448/// struct Config {
449///     a: Column<Advice>,
450///     b: Column<Advice>,
451///     s: Selector,
452/// }
453///
454/// fn circuit_logic<F: Field, C: Chip<F>>(chip: C, mut layouter: impl Layouter<F>) -> Result<(), Error> {
455///     let config = chip.config();
456///     # let config: Config = todo!();
457///     layouter.assign_region(|| "bar", |mut region| {
458///         region.assign_advice(config.a, 0, Value::known(F::ONE));
459///         region.assign_advice(config.b, 1, Value::known(F::ONE));
460///         config.s.enable(&mut region, 1)
461///     })?;
462///     Ok(())
463/// }
464/// ```
465#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
466pub struct Selector(pub(crate) usize, bool);
467
468impl Selector {
469    /// Enable this selector at the given offset within the given region.
470    pub fn enable<F: Field>(&self, region: &mut Region<F>, offset: usize) -> Result<(), Error> {
471        region.enable_selector(|| "", self, offset)
472    }
473
474    /// Is this selector "simple"? Simple selectors can only be multiplied
475    /// by expressions that contain no other simple selectors.
476    pub fn is_simple(&self) -> bool {
477        self.1
478    }
479
480    /// Returns index of this selector
481    pub fn index(&self) -> usize {
482        self.0
483    }
484
485    /// Return expression from selector
486    pub fn expr<F: Field>(&self) -> Expression<F> {
487        Expression::Selector(*self)
488    }
489}
490
491/// Query of fixed column at a certain relative location
492#[derive(Copy, Clone, Debug)]
493pub struct FixedQuery {
494    /// Query index
495    pub(crate) index: Option<usize>,
496    /// Column index
497    pub(crate) column_index: usize,
498    /// Rotation of this query
499    pub(crate) rotation: Rotation,
500}
501
502impl FixedQuery {
503    /// Column index
504    pub fn column_index(&self) -> usize {
505        self.column_index
506    }
507
508    /// Rotation of this query
509    pub fn rotation(&self) -> Rotation {
510        self.rotation
511    }
512}
513
514/// Query of advice column at a certain relative location
515#[derive(Copy, Clone, Debug)]
516pub struct AdviceQuery {
517    /// Query index
518    pub(crate) index: Option<usize>,
519    /// Column index
520    pub(crate) column_index: usize,
521    /// Rotation of this query
522    pub(crate) rotation: Rotation,
523    /// Phase of this advice column
524    pub(crate) phase: sealed::Phase,
525}
526
527impl AdviceQuery {
528    /// Column index
529    pub fn column_index(&self) -> usize {
530        self.column_index
531    }
532
533    /// Rotation of this query
534    pub fn rotation(&self) -> Rotation {
535        self.rotation
536    }
537
538    /// Phase of this advice column
539    pub fn phase(&self) -> u8 {
540        self.phase.0
541    }
542}
543
544/// Query of instance column at a certain relative location
545#[derive(Copy, Clone, Debug)]
546pub struct InstanceQuery {
547    /// Query index
548    pub(crate) index: Option<usize>,
549    /// Column index
550    pub(crate) column_index: usize,
551    /// Rotation of this query
552    pub(crate) rotation: Rotation,
553}
554
555impl InstanceQuery {
556    /// Column index
557    pub fn column_index(&self) -> usize {
558        self.column_index
559    }
560
561    /// Rotation of this query
562    pub fn rotation(&self) -> Rotation {
563        self.rotation
564    }
565}
566
567/// A fixed column of a lookup table.
568///
569/// A lookup table can be loaded into this column via [`Layouter::assign_table`]. Columns
570/// can currently only contain a single table, but they may be used in multiple lookup
571/// arguments via [`ConstraintSystem::lookup`].
572///
573/// Lookup table columns are always "encumbered" by the lookup arguments they are used in;
574/// they cannot simultaneously be used as general fixed columns.
575///
576/// [`Layouter::assign_table`]: crate::circuit::Layouter::assign_table
577#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
578pub struct TableColumn {
579    /// The fixed column that this table column is stored in.
580    ///
581    /// # Security
582    ///
583    /// This inner column MUST NOT be exposed in the public API, or else chip developers
584    /// can load lookup tables into their circuits without default-value-filling the
585    /// columns, which can cause soundness bugs.
586    inner: Column<Fixed>,
587}
588
589impl TableColumn {
590    /// Returns inner column
591    pub fn inner(&self) -> Column<Fixed> {
592        self.inner
593    }
594}
595
596/// A challenge squeezed from transcript after advice columns at the phase have been committed.
597#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
598pub struct Challenge {
599    index: usize,
600    pub(crate) phase: sealed::Phase,
601}
602
603impl Challenge {
604    /// Index of this challenge.
605    pub fn index(&self) -> usize {
606        self.index
607    }
608
609    /// Phase of this challenge.
610    pub fn phase(&self) -> u8 {
611        self.phase.0
612    }
613
614    /// Return Expression
615    pub fn expr<F: Field>(&self) -> Expression<F> {
616        Expression::Challenge(*self)
617    }
618}
619
620/// This trait allows a [`Circuit`] to direct some backend to assign a witness
621/// for a constraint system.
622pub trait Assignment<F: Field> {
623    /// Creates a new region and enters into it.
624    ///
625    /// Panics if we are currently in a region (if `exit_region` was not called).
626    ///
627    /// Not intended for downstream consumption; use [`Layouter::assign_region`] instead.
628    ///
629    /// [`Layouter::assign_region`]: crate::circuit::Layouter#method.assign_region
630    fn enter_region<NR, N>(&mut self, name_fn: N)
631    where
632        NR: Into<String>,
633        N: FnOnce() -> NR;
634
635    /// Allows the developer to include an annotation for an specific column within a `Region`.
636    ///
637    /// This is usually useful for debugging circuit failures.
638    fn annotate_column<A, AR>(&mut self, annotation: A, column: Column<Any>)
639    where
640        A: FnOnce() -> AR,
641        AR: Into<String>;
642
643    /// Exits the current region.
644    ///
645    /// Panics if we are not currently in a region (if `enter_region` was not called).
646    ///
647    /// Not intended for downstream consumption; use [`Layouter::assign_region`] instead.
648    ///
649    /// [`Layouter::assign_region`]: crate::circuit::Layouter#method.assign_region
650    fn exit_region(&mut self);
651
652    /// Enables a selector at the given row.
653    fn enable_selector<A, AR>(
654        &mut self,
655        annotation: A,
656        selector: &Selector,
657        row: usize,
658    ) -> Result<(), Error>
659    where
660        A: FnOnce() -> AR,
661        AR: Into<String>;
662
663    /// Queries the cell of an instance column at a particular absolute row.
664    ///
665    /// Returns the cell's value, if known.
666    fn query_instance(&self, column: Column<Instance>, row: usize) -> Result<Value<F>, Error>;
667
668    /// Assign an advice column value (witness)
669    fn assign_advice<'v>(
670        &mut self,
671        column: Column<Advice>,
672        row: usize,
673        to: Value<Assigned<F>>,
674    ) -> Value<&'v Assigned<F>>;
675
676    /// Assign a fixed value
677    fn assign_fixed(&mut self, column: Column<Fixed>, row: usize, to: Assigned<F>);
678
679    /// Assign two cells to have the same value
680    fn copy(
681        &mut self,
682        left_column: Column<Any>,
683        left_row: usize,
684        right_column: Column<Any>,
685        right_row: usize,
686    );
687
688    /// Fills a fixed `column` starting from the given `row` with value `to`.
689    fn fill_from_row(
690        &mut self,
691        column: Column<Fixed>,
692        row: usize,
693        to: Value<Assigned<F>>,
694    ) -> Result<(), Error>;
695
696    /// Queries the value of the given challenge.
697    ///
698    /// Returns `Value::unknown()` if the current synthesis phase is before the challenge can be queried.
699    fn get_challenge(&self, challenge: Challenge) -> Value<F>;
700
701    /// Creates a new (sub)namespace and enters into it.
702    ///
703    /// Not intended for downstream consumption; use [`Layouter::namespace`] instead.
704    ///
705    /// [`Layouter::namespace`]: crate::circuit::Layouter#method.namespace
706    fn push_namespace<NR, N>(&mut self, name_fn: N)
707    where
708        NR: Into<String>,
709        N: FnOnce() -> NR;
710
711    /// Exits out of the existing namespace.
712    ///
713    /// Not intended for downstream consumption; use [`Layouter::namespace`] instead.
714    ///
715    /// [`Layouter::namespace`]: crate::circuit::Layouter#method.namespace
716    fn pop_namespace(&mut self, gadget_name: Option<String>);
717
718    /// Commit advice columns in current phase and squeeze challenges. This can be
719    /// called DURING synthesize.
720    fn next_phase(&mut self) {}
721}
722
723/// A floor planning strategy for a circuit.
724///
725/// The floor planner is chip-agnostic and applies its strategy to the circuit it is used
726/// within.
727pub trait FloorPlanner {
728    /// Given the provided `cs`, synthesize the given circuit.
729    ///
730    /// `constants` is the list of fixed columns that the layouter may use to assign
731    /// global constant values. These columns will all have been equality-enabled.
732    ///
733    /// Internally, a floor planner will perform the following operations:
734    /// - Instantiate a [`Layouter`] for this floor planner.
735    /// - Perform any necessary setup or measurement tasks, which may involve one or more
736    ///   calls to `Circuit::default().synthesize(config, &mut layouter)`.
737    /// - Call `circuit.synthesize(config, &mut layouter)` exactly once.
738    fn synthesize<F: Field, CS: Assignment<F> + SyncDeps, C: Circuit<F>>(
739        cs: &mut CS,
740        circuit: &C,
741        config: C::Config,
742        constants: Vec<Column<Fixed>>,
743    ) -> Result<(), Error>;
744}
745
746/// This is a trait that circuits provide implementations for so that the
747/// backend prover can ask the circuit to synthesize using some given
748/// [`ConstraintSystem`] implementation.
749pub trait Circuit<F: Field> {
750    /// This is a configuration object that stores things like columns.
751    type Config: Clone;
752    /// The floor planner used for this circuit. This is an associated type of the
753    /// `Circuit` trait because its behaviour is circuit-critical.
754    type FloorPlanner: FloorPlanner;
755    /// Optional circuit configuration parameters. Requires the `circuit-params` feature.
756    #[cfg(feature = "circuit-params")]
757    type Params: Default;
758
759    /// Returns a copy of this circuit with no witness values (i.e. all witnesses set to
760    /// `None`). For most circuits, this will be equal to `Self::default()`.
761    fn without_witnesses(&self) -> Self;
762
763    /// Returns a reference to the parameters that should be used to configure the circuit.
764    /// Requires the `circuit-params` feature.
765    #[cfg(feature = "circuit-params")]
766    fn params(&self) -> Self::Params {
767        Self::Params::default()
768    }
769
770    /// The circuit is given an opportunity to describe the exact gate
771    /// arrangement, column arrangement, etc.  Takes a runtime parameter.  The default
772    /// implementation calls `configure` ignoring the `_params` argument in order to easily support
773    /// circuits that don't use configuration parameters.
774    #[cfg(feature = "circuit-params")]
775    fn configure_with_params(
776        meta: &mut ConstraintSystem<F>,
777        _params: Self::Params,
778    ) -> Self::Config {
779        Self::configure(meta)
780    }
781
782    /// The circuit is given an opportunity to describe the exact gate
783    /// arrangement, column arrangement, etc.
784    fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config;
785
786    /// Given the provided `cs`, synthesize the circuit. The concrete type of
787    /// the caller will be different depending on the context, and they may or
788    /// may not expect to have a witness present.
789    fn synthesize(&self, config: Self::Config, layouter: impl Layouter<F>) -> Result<(), Error>;
790}
791
792/// Low-degree expression representing an identity that must hold over the committed columns.
793#[derive(Clone)]
794pub enum Expression<F> {
795    /// This is a constant polynomial
796    Constant(F),
797    /// This is a virtual selector
798    Selector(Selector),
799    /// This is a fixed column queried at a certain relative location
800    Fixed(FixedQuery),
801    /// This is an advice (witness) column queried at a certain relative location
802    Advice(AdviceQuery),
803    /// This is an instance (external) column queried at a certain relative location
804    Instance(InstanceQuery),
805    /// This is a challenge
806    Challenge(Challenge),
807    /// This is a negated polynomial
808    Negated(Box<Expression<F>>),
809    /// This is the sum of two polynomials
810    Sum(Box<Expression<F>>, Box<Expression<F>>),
811    /// This is the product of two polynomials
812    Product(Box<Expression<F>>, Box<Expression<F>>),
813    /// This is a scaled polynomial
814    Scaled(Box<Expression<F>>, F),
815}
816
817impl<F: Field> Expression<F> {
818    /// Make side effects
819    pub fn query_cells(&mut self, cells: &mut VirtualCells<'_, F>) {
820        match self {
821            Expression::Constant(_) => (),
822            Expression::Selector(selector) => {
823                if !cells.queried_selectors.contains(selector) {
824                    cells.queried_selectors.push(*selector);
825                }
826            }
827            Expression::Fixed(query) => {
828                if query.index.is_none() {
829                    let col = Column {
830                        index: query.column_index,
831                        column_type: Fixed,
832                    };
833                    cells.queried_cells.push((col, query.rotation).into());
834                    query.index = Some(cells.meta.query_fixed_index(col, query.rotation));
835                }
836            }
837            Expression::Advice(query) => {
838                if query.index.is_none() {
839                    let col = Column {
840                        index: query.column_index,
841                        column_type: Advice { phase: query.phase },
842                    };
843                    cells.queried_cells.push((col, query.rotation).into());
844                    query.index = Some(cells.meta.query_advice_index(col, query.rotation));
845                }
846            }
847            Expression::Instance(query) => {
848                if query.index.is_none() {
849                    let col = Column {
850                        index: query.column_index,
851                        column_type: Instance,
852                    };
853                    cells.queried_cells.push((col, query.rotation).into());
854                    query.index = Some(cells.meta.query_instance_index(col, query.rotation));
855                }
856            }
857            Expression::Challenge(_) => (),
858            Expression::Negated(a) => a.query_cells(cells),
859            Expression::Sum(a, b) => {
860                a.query_cells(cells);
861                b.query_cells(cells);
862            }
863            Expression::Product(a, b) => {
864                a.query_cells(cells);
865                b.query_cells(cells);
866            }
867            Expression::Scaled(a, _) => a.query_cells(cells),
868        };
869    }
870
871    /// Evaluate the polynomial using the provided closures to perform the
872    /// operations.
873    #[allow(clippy::too_many_arguments)]
874    pub fn evaluate<T>(
875        &self,
876        constant: &impl Fn(F) -> T,
877        selector_column: &impl Fn(Selector) -> T,
878        fixed_column: &impl Fn(FixedQuery) -> T,
879        advice_column: &impl Fn(AdviceQuery) -> T,
880        instance_column: &impl Fn(InstanceQuery) -> T,
881        challenge: &impl Fn(Challenge) -> T,
882        negated: &impl Fn(T) -> T,
883        sum: &impl Fn(T, T) -> T,
884        product: &impl Fn(T, T) -> T,
885        scaled: &impl Fn(T, F) -> T,
886    ) -> T {
887        match self {
888            Expression::Constant(scalar) => constant(*scalar),
889            Expression::Selector(selector) => selector_column(*selector),
890            Expression::Fixed(query) => fixed_column(*query),
891            Expression::Advice(query) => advice_column(*query),
892            Expression::Instance(query) => instance_column(*query),
893            Expression::Challenge(value) => challenge(*value),
894            Expression::Negated(a) => {
895                let a = a.evaluate(
896                    constant,
897                    selector_column,
898                    fixed_column,
899                    advice_column,
900                    instance_column,
901                    challenge,
902                    negated,
903                    sum,
904                    product,
905                    scaled,
906                );
907                negated(a)
908            }
909            Expression::Sum(a, b) => {
910                let a = a.evaluate(
911                    constant,
912                    selector_column,
913                    fixed_column,
914                    advice_column,
915                    instance_column,
916                    challenge,
917                    negated,
918                    sum,
919                    product,
920                    scaled,
921                );
922                let b = b.evaluate(
923                    constant,
924                    selector_column,
925                    fixed_column,
926                    advice_column,
927                    instance_column,
928                    challenge,
929                    negated,
930                    sum,
931                    product,
932                    scaled,
933                );
934                sum(a, b)
935            }
936            Expression::Product(a, b) => {
937                let a = a.evaluate(
938                    constant,
939                    selector_column,
940                    fixed_column,
941                    advice_column,
942                    instance_column,
943                    challenge,
944                    negated,
945                    sum,
946                    product,
947                    scaled,
948                );
949                let b = b.evaluate(
950                    constant,
951                    selector_column,
952                    fixed_column,
953                    advice_column,
954                    instance_column,
955                    challenge,
956                    negated,
957                    sum,
958                    product,
959                    scaled,
960                );
961                product(a, b)
962            }
963            Expression::Scaled(a, f) => {
964                let a = a.evaluate(
965                    constant,
966                    selector_column,
967                    fixed_column,
968                    advice_column,
969                    instance_column,
970                    challenge,
971                    negated,
972                    sum,
973                    product,
974                    scaled,
975                );
976                scaled(a, *f)
977            }
978        }
979    }
980
981    /// Evaluate the polynomial lazily using the provided closures to perform the
982    /// operations.
983    #[allow(clippy::too_many_arguments)]
984    pub fn evaluate_lazy<T: PartialEq>(
985        &self,
986        constant: &impl Fn(F) -> T,
987        selector_column: &impl Fn(Selector) -> T,
988        fixed_column: &impl Fn(FixedQuery) -> T,
989        advice_column: &impl Fn(AdviceQuery) -> T,
990        instance_column: &impl Fn(InstanceQuery) -> T,
991        challenge: &impl Fn(Challenge) -> T,
992        negated: &impl Fn(T) -> T,
993        sum: &impl Fn(T, T) -> T,
994        product: &impl Fn(T, T) -> T,
995        scaled: &impl Fn(T, F) -> T,
996        zero: &T,
997    ) -> T {
998        match self {
999            Expression::Constant(scalar) => constant(*scalar),
1000            Expression::Selector(selector) => selector_column(*selector),
1001            Expression::Fixed(query) => fixed_column(*query),
1002            Expression::Advice(query) => advice_column(*query),
1003            Expression::Instance(query) => instance_column(*query),
1004            Expression::Challenge(value) => challenge(*value),
1005            Expression::Negated(a) => {
1006                let a = a.evaluate_lazy(
1007                    constant,
1008                    selector_column,
1009                    fixed_column,
1010                    advice_column,
1011                    instance_column,
1012                    challenge,
1013                    negated,
1014                    sum,
1015                    product,
1016                    scaled,
1017                    zero,
1018                );
1019                negated(a)
1020            }
1021            Expression::Sum(a, b) => {
1022                let a = a.evaluate_lazy(
1023                    constant,
1024                    selector_column,
1025                    fixed_column,
1026                    advice_column,
1027                    instance_column,
1028                    challenge,
1029                    negated,
1030                    sum,
1031                    product,
1032                    scaled,
1033                    zero,
1034                );
1035                let b = b.evaluate_lazy(
1036                    constant,
1037                    selector_column,
1038                    fixed_column,
1039                    advice_column,
1040                    instance_column,
1041                    challenge,
1042                    negated,
1043                    sum,
1044                    product,
1045                    scaled,
1046                    zero,
1047                );
1048                sum(a, b)
1049            }
1050            Expression::Product(a, b) => {
1051                let (a, b) = if a.complexity() <= b.complexity() {
1052                    (a, b)
1053                } else {
1054                    (b, a)
1055                };
1056                let a = a.evaluate_lazy(
1057                    constant,
1058                    selector_column,
1059                    fixed_column,
1060                    advice_column,
1061                    instance_column,
1062                    challenge,
1063                    negated,
1064                    sum,
1065                    product,
1066                    scaled,
1067                    zero,
1068                );
1069
1070                if a == *zero {
1071                    a
1072                } else {
1073                    let b = b.evaluate_lazy(
1074                        constant,
1075                        selector_column,
1076                        fixed_column,
1077                        advice_column,
1078                        instance_column,
1079                        challenge,
1080                        negated,
1081                        sum,
1082                        product,
1083                        scaled,
1084                        zero,
1085                    );
1086                    product(a, b)
1087                }
1088            }
1089            Expression::Scaled(a, f) => {
1090                let a = a.evaluate_lazy(
1091                    constant,
1092                    selector_column,
1093                    fixed_column,
1094                    advice_column,
1095                    instance_column,
1096                    challenge,
1097                    negated,
1098                    sum,
1099                    product,
1100                    scaled,
1101                    zero,
1102                );
1103                scaled(a, *f)
1104            }
1105        }
1106    }
1107
1108    fn write_identifier<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
1109        match self {
1110            Expression::Constant(scalar) => write!(writer, "{:?}", scalar),
1111            Expression::Selector(selector) => write!(writer, "selector[{}]", selector.0),
1112            Expression::Fixed(query) => {
1113                write!(
1114                    writer,
1115                    "fixed[{}][{}]",
1116                    query.column_index, query.rotation.0
1117                )
1118            }
1119            Expression::Advice(query) => {
1120                write!(
1121                    writer,
1122                    "advice[{}][{}]",
1123                    query.column_index, query.rotation.0
1124                )
1125            }
1126            Expression::Instance(query) => {
1127                write!(
1128                    writer,
1129                    "instance[{}][{}]",
1130                    query.column_index, query.rotation.0
1131                )
1132            }
1133            Expression::Challenge(challenge) => {
1134                write!(writer, "challenge[{}]", challenge.index())
1135            }
1136            Expression::Negated(a) => {
1137                writer.write_all(b"(-")?;
1138                a.write_identifier(writer)?;
1139                writer.write_all(b")")
1140            }
1141            Expression::Sum(a, b) => {
1142                writer.write_all(b"(")?;
1143                a.write_identifier(writer)?;
1144                writer.write_all(b"+")?;
1145                b.write_identifier(writer)?;
1146                writer.write_all(b")")
1147            }
1148            Expression::Product(a, b) => {
1149                writer.write_all(b"(")?;
1150                a.write_identifier(writer)?;
1151                writer.write_all(b"*")?;
1152                b.write_identifier(writer)?;
1153                writer.write_all(b")")
1154            }
1155            Expression::Scaled(a, f) => {
1156                a.write_identifier(writer)?;
1157                write!(writer, "*{:?}", f)
1158            }
1159        }
1160    }
1161
1162    /// Identifier for this expression. Expressions with identical identifiers
1163    /// do the same calculation (but the expressions don't need to be exactly equal
1164    /// in how they are composed e.g. `1 + 2` and `2 + 1` can have the same identifier).
1165    pub fn identifier(&self) -> String {
1166        let mut cursor = std::io::Cursor::new(Vec::new());
1167        self.write_identifier(&mut cursor).unwrap();
1168        String::from_utf8(cursor.into_inner()).unwrap()
1169    }
1170
1171    /// Compute the degree of this polynomial
1172    pub fn degree(&self) -> usize {
1173        match self {
1174            Expression::Constant(_) => 0,
1175            Expression::Selector(_) => 1,
1176            Expression::Fixed(_) => 1,
1177            Expression::Advice(_) => 1,
1178            Expression::Instance(_) => 1,
1179            Expression::Challenge(_) => 0,
1180            Expression::Negated(poly) => poly.degree(),
1181            Expression::Sum(a, b) => max(a.degree(), b.degree()),
1182            Expression::Product(a, b) => a.degree() + b.degree(),
1183            Expression::Scaled(poly, _) => poly.degree(),
1184        }
1185    }
1186
1187    /// Approximate the computational complexity of this expression.
1188    pub fn complexity(&self) -> usize {
1189        match self {
1190            Expression::Constant(_) => 0,
1191            Expression::Selector(_) => 1,
1192            Expression::Fixed(_) => 1,
1193            Expression::Advice(_) => 1,
1194            Expression::Instance(_) => 1,
1195            Expression::Challenge(_) => 0,
1196            Expression::Negated(poly) => poly.complexity() + 5,
1197            Expression::Sum(a, b) => a.complexity() + b.complexity() + 15,
1198            Expression::Product(a, b) => a.complexity() + b.complexity() + 30,
1199            Expression::Scaled(poly, _) => poly.complexity() + 30,
1200        }
1201    }
1202
1203    /// Square this expression.
1204    pub fn square(self) -> Self {
1205        self.clone() * self
1206    }
1207
1208    /// Returns whether or not this expression contains a simple `Selector`.
1209    fn contains_simple_selector(&self) -> bool {
1210        self.evaluate(
1211            &|_| false,
1212            &|selector| selector.is_simple(),
1213            &|_| false,
1214            &|_| false,
1215            &|_| false,
1216            &|_| false,
1217            &|a| a,
1218            &|a, b| a || b,
1219            &|a, b| a || b,
1220            &|a, _| a,
1221        )
1222    }
1223
1224    /// Extracts a simple selector from this gate, if present
1225    fn extract_simple_selector(&self) -> Option<Selector> {
1226        let op = |a, b| match (a, b) {
1227            (Some(a), None) | (None, Some(a)) => Some(a),
1228            (Some(_), Some(_)) => panic!("two simple selectors cannot be in the same expression"),
1229            _ => None,
1230        };
1231
1232        self.evaluate(
1233            &|_| None,
1234            &|selector| {
1235                if selector.is_simple() {
1236                    Some(selector)
1237                } else {
1238                    None
1239                }
1240            },
1241            &|_| None,
1242            &|_| None,
1243            &|_| None,
1244            &|_| None,
1245            &|a| a,
1246            &op,
1247            &op,
1248            &|a, _| a,
1249        )
1250    }
1251
1252    /// Extracts all used instance columns in this expression
1253    pub fn extract_instances(&self) -> Vec<usize> {
1254        self.evaluate(
1255            &|_| vec![],
1256            &|_| vec![],
1257            &|_| vec![],
1258            &|_| vec![],
1259            &|query| vec![query.column_index],
1260            &|_| vec![],
1261            &|a| a,
1262            &|mut a, b| {
1263                a.extend(b);
1264                a.into_iter().unique().collect()
1265            },
1266            &|mut a, b| {
1267                a.extend(b);
1268                a.into_iter().unique().collect()
1269            },
1270            &|a, _| a,
1271        )
1272    }
1273
1274    /// Extracts all used advice columns in this expression
1275    pub fn extract_advices(&self) -> Vec<usize> {
1276        self.evaluate(
1277            &|_| vec![],
1278            &|_| vec![],
1279            &|_| vec![],
1280            &|query| vec![query.column_index],
1281            &|_| vec![],
1282            &|_| vec![],
1283            &|a| a,
1284            &|mut a, b| {
1285                a.extend(b);
1286                a.into_iter().unique().collect()
1287            },
1288            &|mut a, b| {
1289                a.extend(b);
1290                a.into_iter().unique().collect()
1291            },
1292            &|a, _| a,
1293        )
1294    }
1295
1296    /// Extracts all used fixed columns in this expression
1297    pub fn extract_fixed(&self) -> Vec<usize> {
1298        self.evaluate(
1299            &|_| vec![],
1300            &|_| vec![],
1301            &|query| vec![query.column_index],
1302            &|_| vec![],
1303            &|_| vec![],
1304            &|_| vec![],
1305            &|a| a,
1306            &|mut a, b| {
1307                a.extend(b);
1308                a.into_iter().unique().collect()
1309            },
1310            &|mut a, b| {
1311                a.extend(b);
1312                a.into_iter().unique().collect()
1313            },
1314            &|a, _| a,
1315        )
1316    }
1317}
1318
1319impl<F: std::fmt::Debug> std::fmt::Debug for Expression<F> {
1320    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1321        match self {
1322            Expression::Constant(scalar) => f.debug_tuple("Constant").field(scalar).finish(),
1323            Expression::Selector(selector) => f.debug_tuple("Selector").field(selector).finish(),
1324            // Skip enum variant and print query struct directly to maintain backwards compatibility.
1325            Expression::Fixed(query) => {
1326                let mut debug_struct = f.debug_struct("Fixed");
1327                match query.index {
1328                    None => debug_struct.field("query_index", &query.index),
1329                    Some(idx) => debug_struct.field("query_index", &idx),
1330                };
1331                debug_struct
1332                    .field("column_index", &query.column_index)
1333                    .field("rotation", &query.rotation)
1334                    .finish()
1335            }
1336            Expression::Advice(query) => {
1337                let mut debug_struct = f.debug_struct("Advice");
1338                match query.index {
1339                    None => debug_struct.field("query_index", &query.index),
1340                    Some(idx) => debug_struct.field("query_index", &idx),
1341                };
1342                debug_struct
1343                    .field("column_index", &query.column_index)
1344                    .field("rotation", &query.rotation);
1345                // Only show advice's phase if it's not in first phase.
1346                if query.phase != FirstPhase.to_sealed() {
1347                    debug_struct.field("phase", &query.phase);
1348                }
1349                debug_struct.finish()
1350            }
1351            Expression::Instance(query) => {
1352                let mut debug_struct = f.debug_struct("Instance");
1353                match query.index {
1354                    None => debug_struct.field("query_index", &query.index),
1355                    Some(idx) => debug_struct.field("query_index", &idx),
1356                };
1357                debug_struct
1358                    .field("column_index", &query.column_index)
1359                    .field("rotation", &query.rotation)
1360                    .finish()
1361            }
1362            Expression::Challenge(challenge) => {
1363                f.debug_tuple("Challenge").field(challenge).finish()
1364            }
1365            Expression::Negated(poly) => f.debug_tuple("Negated").field(poly).finish(),
1366            Expression::Sum(a, b) => f.debug_tuple("Sum").field(a).field(b).finish(),
1367            Expression::Product(a, b) => f.debug_tuple("Product").field(a).field(b).finish(),
1368            Expression::Scaled(poly, scalar) => {
1369                f.debug_tuple("Scaled").field(poly).field(scalar).finish()
1370            }
1371        }
1372    }
1373}
1374
1375impl<F: Field> Neg for Expression<F> {
1376    type Output = Expression<F>;
1377    fn neg(self) -> Self::Output {
1378        Expression::Negated(Box::new(self))
1379    }
1380}
1381
1382impl<F: Field> Add for Expression<F> {
1383    type Output = Expression<F>;
1384    fn add(self, rhs: Expression<F>) -> Expression<F> {
1385        if self.contains_simple_selector() || rhs.contains_simple_selector() {
1386            panic!("attempted to use a simple selector in an addition");
1387        }
1388        Expression::Sum(Box::new(self), Box::new(rhs))
1389    }
1390}
1391
1392impl<F: Field> Sub for Expression<F> {
1393    type Output = Expression<F>;
1394    fn sub(self, rhs: Expression<F>) -> Expression<F> {
1395        if self.contains_simple_selector() || rhs.contains_simple_selector() {
1396            panic!("attempted to use a simple selector in a subtraction");
1397        }
1398        Expression::Sum(Box::new(self), Box::new(-rhs))
1399    }
1400}
1401
1402impl<F: Field> Mul for Expression<F> {
1403    type Output = Expression<F>;
1404    fn mul(self, rhs: Expression<F>) -> Expression<F> {
1405        if self.contains_simple_selector() && rhs.contains_simple_selector() {
1406            panic!("attempted to multiply two expressions containing simple selectors");
1407        }
1408        Expression::Product(Box::new(self), Box::new(rhs))
1409    }
1410}
1411
1412impl<F: Field> Mul<F> for Expression<F> {
1413    type Output = Expression<F>;
1414    fn mul(self, rhs: F) -> Expression<F> {
1415        Expression::Scaled(Box::new(self), rhs)
1416    }
1417}
1418
1419/// Represents an index into a vector where each entry corresponds to a distinct
1420/// point that polynomials are queried at.
1421#[derive(Copy, Clone, Debug)]
1422pub(crate) struct PointIndex(pub usize);
1423
1424/// A "virtual cell" is a PLONK cell that has been queried at a particular relative offset
1425/// within a custom gate.
1426#[derive(Clone, Debug)]
1427pub struct VirtualCell {
1428    pub(crate) column: Column<Any>,
1429    pub(crate) rotation: Rotation,
1430}
1431
1432impl<Col: Into<Column<Any>>> From<(Col, Rotation)> for VirtualCell {
1433    fn from((column, rotation): (Col, Rotation)) -> Self {
1434        VirtualCell {
1435            column: column.into(),
1436            rotation,
1437        }
1438    }
1439}
1440
1441/// An individual polynomial constraint.
1442///
1443/// These are returned by the closures passed to `ConstraintSystem::create_gate`.
1444#[derive(Debug)]
1445pub struct Constraint<F: Field> {
1446    name: String,
1447    poly: Expression<F>,
1448}
1449
1450impl<F: Field> From<Expression<F>> for Constraint<F> {
1451    fn from(poly: Expression<F>) -> Self {
1452        Constraint {
1453            name: "".to_string(),
1454            poly,
1455        }
1456    }
1457}
1458
1459impl<F: Field, S: AsRef<str>> From<(S, Expression<F>)> for Constraint<F> {
1460    fn from((name, poly): (S, Expression<F>)) -> Self {
1461        Constraint {
1462            name: name.as_ref().to_string(),
1463            poly,
1464        }
1465    }
1466}
1467
1468impl<F: Field> From<Expression<F>> for Vec<Constraint<F>> {
1469    fn from(poly: Expression<F>) -> Self {
1470        vec![Constraint {
1471            name: "".to_string(),
1472            poly,
1473        }]
1474    }
1475}
1476
1477/// A set of polynomial constraints with a common selector.
1478///
1479/// ```
1480/// use halo2_axiom::{plonk::{Constraints, Expression}, poly::Rotation};
1481/// use halo2curves::pasta::Fp;
1482/// # use halo2_axiom::plonk::ConstraintSystem;
1483///
1484/// # let mut meta = ConstraintSystem::<Fp>::default();
1485/// let a = meta.advice_column();
1486/// let b = meta.advice_column();
1487/// let c = meta.advice_column();
1488/// let s = meta.selector();
1489///
1490/// meta.create_gate("foo", |meta| {
1491///     let next = meta.query_advice(a, Rotation::next());
1492///     let a = meta.query_advice(a, Rotation::cur());
1493///     let b = meta.query_advice(b, Rotation::cur());
1494///     let c = meta.query_advice(c, Rotation::cur());
1495///     let s_ternary = meta.query_selector(s);
1496///
1497///     let one_minus_a = Expression::Constant(Fp::one()) - a.clone();
1498///
1499///     Constraints::with_selector(
1500///         s_ternary,
1501///         std::array::IntoIter::new([
1502///             ("a is boolean", a.clone() * one_minus_a.clone()),
1503///             ("next == a ? b : c", next - (a * b + one_minus_a * c)),
1504///         ]),
1505///     )
1506/// });
1507/// ```
1508///
1509/// Note that the use of `std::array::IntoIter::new` is only necessary if you need to
1510/// support Rust 1.51 or 1.52. If your minimum supported Rust version is 1.53 or greater,
1511/// you can pass an array directly.
1512#[derive(Debug)]
1513pub struct Constraints<F: Field, C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>> {
1514    selector: Expression<F>,
1515    constraints: Iter,
1516}
1517
1518impl<F: Field, C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>> Constraints<F, C, Iter> {
1519    /// Constructs a set of constraints that are controlled by the given selector.
1520    ///
1521    /// Each constraint `c` in `iterator` will be converted into the constraint
1522    /// `selector * c`.
1523    pub fn with_selector(selector: Expression<F>, constraints: Iter) -> Self {
1524        Constraints {
1525            selector,
1526            constraints,
1527        }
1528    }
1529}
1530
1531fn apply_selector_to_constraint<F: Field, C: Into<Constraint<F>>>(
1532    (selector, c): (Expression<F>, C),
1533) -> Constraint<F> {
1534    let constraint: Constraint<F> = c.into();
1535    Constraint {
1536        name: constraint.name,
1537        poly: selector * constraint.poly,
1538    }
1539}
1540
1541type ApplySelectorToConstraint<F, C> = fn((Expression<F>, C)) -> Constraint<F>;
1542type ConstraintsIterator<F, C, I> = std::iter::Map<
1543    std::iter::Zip<std::iter::Repeat<Expression<F>>, I>,
1544    ApplySelectorToConstraint<F, C>,
1545>;
1546
1547impl<F: Field, C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>> IntoIterator
1548    for Constraints<F, C, Iter>
1549{
1550    type Item = Constraint<F>;
1551    type IntoIter = ConstraintsIterator<F, C, Iter::IntoIter>;
1552
1553    fn into_iter(self) -> Self::IntoIter {
1554        std::iter::repeat(self.selector)
1555            .zip(self.constraints)
1556            .map(apply_selector_to_constraint)
1557    }
1558}
1559
1560/// Gate
1561#[derive(Clone, Debug)]
1562pub struct Gate<F: Field> {
1563    name: String,
1564    constraint_names: Vec<String>,
1565    polys: Vec<Expression<F>>,
1566    /// We track queried selectors separately from other cells, so that we can use them to
1567    /// trigger debug checks on gates.
1568    queried_selectors: Vec<Selector>,
1569    queried_cells: Vec<VirtualCell>,
1570}
1571
1572impl<F: Field> Gate<F> {
1573    /// Returns the gate name.
1574    pub fn name(&self) -> &str {
1575        self.name.as_str()
1576    }
1577
1578    /// Returns the name of the constraint at index `constraint_index`.
1579    pub fn constraint_name(&self, constraint_index: usize) -> &str {
1580        self.constraint_names[constraint_index].as_str()
1581    }
1582
1583    /// Returns constraints of this gate
1584    pub fn polynomials(&self) -> &[Expression<F>] {
1585        &self.polys
1586    }
1587
1588    pub(crate) fn queried_selectors(&self) -> &[Selector] {
1589        &self.queried_selectors
1590    }
1591
1592    pub(crate) fn queried_cells(&self) -> &[VirtualCell] {
1593        &self.queried_cells
1594    }
1595}
1596
1597/// This is a description of the circuit environment, such as the gate, column and
1598/// permutation arrangements.
1599#[derive(Debug, Clone)]
1600pub struct ConstraintSystem<F: Field> {
1601    pub(crate) num_fixed_columns: usize,
1602    pub(crate) num_advice_columns: usize,
1603    pub(crate) num_instance_columns: usize,
1604    pub(crate) num_selectors: usize,
1605    pub(crate) num_challenges: usize,
1606
1607    /// Contains the phase for each advice column. Should have same length as num_advice_columns.
1608    pub(crate) advice_column_phase: Vec<sealed::Phase>,
1609    /// Contains the phase for each challenge. Should have same length as num_challenges.
1610    pub(crate) challenge_phase: Vec<sealed::Phase>,
1611
1612    /// This is a cached vector that maps virtual selectors to the concrete
1613    /// fixed column that they were compressed into. This is just used by dev
1614    /// tooling right now.
1615    pub(crate) selector_map: Vec<Column<Fixed>>,
1616
1617    pub(crate) gates: Vec<Gate<F>>,
1618    pub(crate) advice_queries: Vec<(Column<Advice>, Rotation)>,
1619    // Contains an integer for each advice column
1620    // identifying how many distinct queries it has
1621    // so far; should be same length as num_advice_columns.
1622    num_advice_queries: Vec<usize>,
1623    pub(crate) instance_queries: Vec<(Column<Instance>, Rotation)>,
1624    pub(crate) fixed_queries: Vec<(Column<Fixed>, Rotation)>,
1625
1626    // Permutation argument for performing equality constraints
1627    pub(crate) permutation: permutation::Argument,
1628
1629    // Vector of lookup arguments, where each corresponds to a sequence of
1630    // input expressions and a sequence of table expressions involved in the lookup.
1631    pub(crate) lookups: Vec<lookup::Argument<F>>,
1632
1633    // List of indexes of Fixed columns which are associated to a circuit-general Column tied to their annotation.
1634    pub(crate) general_column_annotations: HashMap<metadata::Column, String>,
1635
1636    // Vector of fixed columns, which can be used to store constant values
1637    // that are copied into advice columns.
1638    pub(crate) constants: Vec<Column<Fixed>>,
1639
1640    pub(crate) minimum_degree: Option<usize>,
1641}
1642
1643/// Represents the minimal parameters that determine a `ConstraintSystem`.
1644#[allow(dead_code)]
1645pub struct PinnedConstraintSystem<'a, F: Field> {
1646    num_fixed_columns: &'a usize,
1647    num_advice_columns: &'a usize,
1648    num_instance_columns: &'a usize,
1649    num_selectors: &'a usize,
1650    num_challenges: &'a usize,
1651    advice_column_phase: &'a Vec<sealed::Phase>,
1652    challenge_phase: &'a Vec<sealed::Phase>,
1653    gates: PinnedGates<'a, F>,
1654    advice_queries: &'a Vec<(Column<Advice>, Rotation)>,
1655    instance_queries: &'a Vec<(Column<Instance>, Rotation)>,
1656    fixed_queries: &'a Vec<(Column<Fixed>, Rotation)>,
1657    permutation: &'a permutation::Argument,
1658    lookups: &'a Vec<lookup::Argument<F>>,
1659    constants: &'a Vec<Column<Fixed>>,
1660    minimum_degree: &'a Option<usize>,
1661}
1662
1663impl<'a, F: Field> std::fmt::Debug for PinnedConstraintSystem<'a, F> {
1664    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1665        let mut debug_struct = f.debug_struct("PinnedConstraintSystem");
1666        debug_struct
1667            .field("num_fixed_columns", self.num_fixed_columns)
1668            .field("num_advice_columns", self.num_advice_columns)
1669            .field("num_instance_columns", self.num_instance_columns)
1670            .field("num_selectors", self.num_selectors);
1671        // Only show multi-phase related fields if it's used.
1672        if *self.num_challenges > 0 {
1673            debug_struct
1674                .field("num_challenges", self.num_challenges)
1675                .field("advice_column_phase", self.advice_column_phase)
1676                .field("challenge_phase", self.challenge_phase);
1677        }
1678        debug_struct
1679            .field("gates", &self.gates)
1680            .field("advice_queries", self.advice_queries)
1681            .field("instance_queries", self.instance_queries)
1682            .field("fixed_queries", self.fixed_queries)
1683            .field("permutation", self.permutation)
1684            .field("lookups", self.lookups)
1685            .field("constants", self.constants)
1686            .field("minimum_degree", self.minimum_degree);
1687        debug_struct.finish()
1688    }
1689}
1690
1691struct PinnedGates<'a, F: Field>(&'a Vec<Gate<F>>);
1692
1693impl<'a, F: Field> std::fmt::Debug for PinnedGates<'a, F> {
1694    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
1695        f.debug_list()
1696            .entries(self.0.iter().flat_map(|gate| gate.polynomials().iter()))
1697            .finish()
1698    }
1699}
1700
1701impl<F: Field> Default for ConstraintSystem<F> {
1702    fn default() -> ConstraintSystem<F> {
1703        ConstraintSystem {
1704            num_fixed_columns: 0,
1705            num_advice_columns: 0,
1706            num_instance_columns: 0,
1707            num_selectors: 0,
1708            num_challenges: 0,
1709            advice_column_phase: Vec::new(),
1710            challenge_phase: Vec::new(),
1711            selector_map: vec![],
1712            gates: vec![],
1713            fixed_queries: Vec::new(),
1714            advice_queries: Vec::new(),
1715            num_advice_queries: Vec::new(),
1716            instance_queries: Vec::new(),
1717            permutation: permutation::Argument::new(),
1718            lookups: Vec::new(),
1719            general_column_annotations: HashMap::new(),
1720            constants: vec![],
1721            minimum_degree: None,
1722        }
1723    }
1724}
1725
1726impl<F: Field> ConstraintSystem<F> {
1727    /// Obtain a pinned version of this constraint system; a structure with the
1728    /// minimal parameters needed to determine the rest of the constraint
1729    /// system.
1730    pub fn pinned(&self) -> PinnedConstraintSystem<'_, F> {
1731        PinnedConstraintSystem {
1732            num_fixed_columns: &self.num_fixed_columns,
1733            num_advice_columns: &self.num_advice_columns,
1734            num_instance_columns: &self.num_instance_columns,
1735            num_selectors: &self.num_selectors,
1736            num_challenges: &self.num_challenges,
1737            advice_column_phase: &self.advice_column_phase,
1738            challenge_phase: &self.challenge_phase,
1739            gates: PinnedGates(&self.gates),
1740            fixed_queries: &self.fixed_queries,
1741            advice_queries: &self.advice_queries,
1742            instance_queries: &self.instance_queries,
1743            permutation: &self.permutation,
1744            lookups: &self.lookups,
1745            constants: &self.constants,
1746            minimum_degree: &self.minimum_degree,
1747        }
1748    }
1749
1750    /// Enables this fixed column to be used for global constant assignments.
1751    ///
1752    /// # Side-effects
1753    ///
1754    /// The column will be equality-enabled.
1755    pub fn enable_constant(&mut self, column: Column<Fixed>) {
1756        if !self.constants.contains(&column) {
1757            self.constants.push(column);
1758            self.enable_equality(column);
1759        }
1760    }
1761
1762    /// Enable the ability to enforce equality over cells in this column
1763    pub fn enable_equality<C: Into<Column<Any>>>(&mut self, column: C) {
1764        let column = column.into();
1765        self.query_any_index(column, Rotation::cur());
1766        self.permutation.add_column(column);
1767    }
1768
1769    /// Add a lookup argument for some input expressions and table columns.
1770    ///
1771    /// `table_map` returns a map between input expressions and the table columns
1772    /// they need to match.
1773    pub fn lookup<S: AsRef<str>>(
1774        &mut self,
1775        name: S,
1776        table_map: impl FnOnce(&mut VirtualCells<'_, F>) -> Vec<(Expression<F>, TableColumn)>,
1777    ) -> usize {
1778        let mut cells = VirtualCells::new(self);
1779        let table_map = table_map(&mut cells)
1780            .into_iter()
1781            .map(|(mut input, table)| {
1782                if input.contains_simple_selector() {
1783                    panic!("expression containing simple selector supplied to lookup argument");
1784                }
1785                let mut table = cells.query_fixed(table.inner(), Rotation::cur());
1786                input.query_cells(&mut cells);
1787                table.query_cells(&mut cells);
1788                (input, table)
1789            })
1790            .collect();
1791        let index = self.lookups.len();
1792
1793        self.lookups
1794            .push(lookup::Argument::new(name.as_ref(), table_map));
1795
1796        index
1797    }
1798
1799    /// Add a lookup argument for some input expressions and table expressions.
1800    ///
1801    /// `table_map` returns a map between input expressions and the table expressions
1802    /// they need to match.
1803    pub fn lookup_any<S: AsRef<str>>(
1804        &mut self,
1805        name: S,
1806        table_map: impl FnOnce(&mut VirtualCells<'_, F>) -> Vec<(Expression<F>, Expression<F>)>,
1807    ) -> usize {
1808        let mut cells = VirtualCells::new(self);
1809        let table_map = table_map(&mut cells)
1810            .into_iter()
1811            .map(|(mut input, mut table)| {
1812                input.query_cells(&mut cells);
1813                table.query_cells(&mut cells);
1814                (input, table)
1815            })
1816            .collect();
1817        let index = self.lookups.len();
1818
1819        self.lookups
1820            .push(lookup::Argument::new(name.as_ref(), table_map));
1821
1822        index
1823    }
1824
1825    fn query_fixed_index(&mut self, column: Column<Fixed>, at: Rotation) -> usize {
1826        // Return existing query, if it exists
1827        for (index, fixed_query) in self.fixed_queries.iter().enumerate() {
1828            if fixed_query == &(column, at) {
1829                return index;
1830            }
1831        }
1832
1833        // Make a new query
1834        let index = self.fixed_queries.len();
1835        self.fixed_queries.push((column, at));
1836
1837        index
1838    }
1839
1840    pub(crate) fn query_advice_index(&mut self, column: Column<Advice>, at: Rotation) -> usize {
1841        // Return existing query, if it exists
1842        for (index, advice_query) in self.advice_queries.iter().enumerate() {
1843            if advice_query == &(column, at) {
1844                return index;
1845            }
1846        }
1847
1848        // Make a new query
1849        let index = self.advice_queries.len();
1850        self.advice_queries.push((column, at));
1851        self.num_advice_queries[column.index] += 1;
1852
1853        index
1854    }
1855
1856    fn query_instance_index(&mut self, column: Column<Instance>, at: Rotation) -> usize {
1857        // Return existing query, if it exists
1858        for (index, instance_query) in self.instance_queries.iter().enumerate() {
1859            if instance_query == &(column, at) {
1860                return index;
1861            }
1862        }
1863
1864        // Make a new query
1865        let index = self.instance_queries.len();
1866        self.instance_queries.push((column, at));
1867
1868        index
1869    }
1870
1871    fn query_any_index(&mut self, column: Column<Any>, at: Rotation) -> usize {
1872        match column.column_type() {
1873            Any::Advice(_) => {
1874                self.query_advice_index(Column::<Advice>::try_from(column).unwrap(), at)
1875            }
1876            Any::Fixed => self.query_fixed_index(Column::<Fixed>::try_from(column).unwrap(), at),
1877            Any::Instance => {
1878                self.query_instance_index(Column::<Instance>::try_from(column).unwrap(), at)
1879            }
1880        }
1881    }
1882
1883    pub(crate) fn get_advice_query_index(&self, column: Column<Advice>, at: Rotation) -> usize {
1884        for (index, advice_query) in self.advice_queries.iter().enumerate() {
1885            if advice_query == &(column, at) {
1886                return index;
1887            }
1888        }
1889
1890        panic!("get_advice_query_index called for non-existent query");
1891    }
1892
1893    pub(crate) fn get_fixed_query_index(&self, column: Column<Fixed>, at: Rotation) -> usize {
1894        for (index, fixed_query) in self.fixed_queries.iter().enumerate() {
1895            if fixed_query == &(column, at) {
1896                return index;
1897            }
1898        }
1899
1900        panic!("get_fixed_query_index called for non-existent query");
1901    }
1902
1903    pub(crate) fn get_instance_query_index(&self, column: Column<Instance>, at: Rotation) -> usize {
1904        for (index, instance_query) in self.instance_queries.iter().enumerate() {
1905            if instance_query == &(column, at) {
1906                return index;
1907            }
1908        }
1909
1910        panic!("get_instance_query_index called for non-existent query");
1911    }
1912
1913    pub(crate) fn get_any_query_index(&self, column: Column<Any>, at: Rotation) -> usize {
1914        match column.column_type() {
1915            Any::Advice(_) => {
1916                self.get_advice_query_index(Column::<Advice>::try_from(column).unwrap(), at)
1917            }
1918            Any::Fixed => {
1919                self.get_fixed_query_index(Column::<Fixed>::try_from(column).unwrap(), at)
1920            }
1921            Any::Instance => {
1922                self.get_instance_query_index(Column::<Instance>::try_from(column).unwrap(), at)
1923            }
1924        }
1925    }
1926
1927    /// Sets the minimum degree required by the circuit, which can be set to a
1928    /// larger amount than actually needed. This can be used, for example, to
1929    /// force the permutation argument to involve more columns in the same set.
1930    pub fn set_minimum_degree(&mut self, degree: usize) {
1931        self.minimum_degree = Some(degree);
1932    }
1933
1934    /// Creates a new gate.
1935    ///
1936    /// # Panics
1937    ///
1938    /// A gate is required to contain polynomial constraints. This method will panic if
1939    /// `constraints` returns an empty iterator.
1940    pub fn create_gate<C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>, S: AsRef<str>>(
1941        &mut self,
1942        name: S,
1943        constraints: impl FnOnce(&mut VirtualCells<'_, F>) -> Iter,
1944    ) {
1945        let mut cells = VirtualCells::new(self);
1946        let constraints = constraints(&mut cells);
1947        let (constraint_names, polys): (_, Vec<_>) = constraints
1948            .into_iter()
1949            .map(|c| c.into())
1950            .map(|mut c: Constraint<F>| {
1951                c.poly.query_cells(&mut cells);
1952                (c.name, c.poly)
1953            })
1954            .unzip();
1955
1956        let queried_selectors = cells.queried_selectors;
1957        let queried_cells = cells.queried_cells;
1958
1959        assert!(
1960            !polys.is_empty(),
1961            "Gates must contain at least one constraint."
1962        );
1963
1964        self.gates.push(Gate {
1965            name: name.as_ref().to_string(),
1966            constraint_names,
1967            polys,
1968            queried_selectors,
1969            queried_cells,
1970        });
1971    }
1972
1973    /// This will compress selectors together depending on their provided
1974    /// assignments. This `ConstraintSystem` will then be modified to add new
1975    /// fixed columns (representing the actual selectors) and will return the
1976    /// polynomials for those columns. Finally, an internal map is updated to
1977    /// find which fixed column corresponds with a given `Selector`.
1978    ///
1979    /// Do not call this twice. Yes, this should be a builder pattern instead.
1980    pub fn compress_selectors(mut self, selectors: Vec<Vec<bool>>) -> (Self, Vec<Vec<F>>) {
1981        // The number of provided selector assignments must be the number we
1982        // counted for this constraint system.
1983        assert_eq!(selectors.len(), self.num_selectors);
1984
1985        // Compute the maximal degree of every selector. We only consider the
1986        // expressions in gates, as lookup arguments cannot support simple
1987        // selectors. Selectors that are complex or do not appear in any gates
1988        // will have degree zero.
1989        let mut degrees = vec![0; selectors.len()];
1990        for expr in self.gates.iter().flat_map(|gate| gate.polys.iter()) {
1991            if let Some(selector) = expr.extract_simple_selector() {
1992                degrees[selector.0] = max(degrees[selector.0], expr.degree());
1993            }
1994        }
1995
1996        // We will not increase the degree of the constraint system, so we limit
1997        // ourselves to the largest existing degree constraint.
1998        let max_degree = self.degree();
1999
2000        let mut new_columns = vec![];
2001        let (polys, selector_assignment) = compress_selectors::process(
2002            selectors
2003                .into_iter()
2004                .zip(degrees)
2005                .enumerate()
2006                .map(
2007                    |(i, (activations, max_degree))| compress_selectors::SelectorDescription {
2008                        selector: i,
2009                        activations,
2010                        max_degree,
2011                    },
2012                )
2013                .collect(),
2014            max_degree,
2015            || {
2016                let column = self.fixed_column();
2017                new_columns.push(column);
2018                Expression::Fixed(FixedQuery {
2019                    index: Some(self.query_fixed_index(column, Rotation::cur())),
2020                    column_index: column.index,
2021                    rotation: Rotation::cur(),
2022                })
2023            },
2024        );
2025
2026        let mut selector_map = vec![None; selector_assignment.len()];
2027        let mut selector_replacements = vec![None; selector_assignment.len()];
2028        for assignment in selector_assignment {
2029            selector_replacements[assignment.selector] = Some(assignment.expression);
2030            selector_map[assignment.selector] = Some(new_columns[assignment.combination_index]);
2031        }
2032
2033        self.selector_map = selector_map
2034            .into_iter()
2035            .map(|a| a.unwrap())
2036            .collect::<Vec<_>>();
2037        let selector_replacements = selector_replacements
2038            .into_iter()
2039            .map(|a| a.unwrap())
2040            .collect::<Vec<_>>();
2041        self.replace_selectors_with_fixed(&selector_replacements);
2042
2043        (self, polys)
2044    }
2045
2046    /// Does not combine selectors and directly replaces them everywhere with fixed columns.
2047    pub fn directly_convert_selectors_to_fixed(
2048        mut self,
2049        selectors: Vec<Vec<bool>>,
2050    ) -> (Self, Vec<Vec<F>>) {
2051        // The number of provided selector assignments must be the number we
2052        // counted for this constraint system.
2053        assert_eq!(selectors.len(), self.num_selectors);
2054
2055        let (polys, selector_replacements): (Vec<_>, Vec<_>) = selectors
2056            .into_iter()
2057            .map(|selector| {
2058                let poly = selector
2059                    .iter()
2060                    .map(|b| if *b { F::ONE } else { F::ZERO })
2061                    .collect::<Vec<_>>();
2062                let column = self.fixed_column();
2063                let rotation = Rotation::cur();
2064                let expr = Expression::Fixed(FixedQuery {
2065                    index: Some(self.query_fixed_index(column, rotation)),
2066                    column_index: column.index,
2067                    rotation,
2068                });
2069                (poly, expr)
2070            })
2071            .unzip();
2072
2073        self.replace_selectors_with_fixed(&selector_replacements);
2074        self.num_selectors = 0;
2075
2076        (self, polys)
2077    }
2078
2079    fn replace_selectors_with_fixed(&mut self, selector_replacements: &[Expression<F>]) {
2080        fn replace_selectors<F: Field>(
2081            expr: &mut Expression<F>,
2082            selector_replacements: &[Expression<F>],
2083            must_be_nonsimple: bool,
2084        ) {
2085            *expr = expr.evaluate(
2086                &|constant| Expression::Constant(constant),
2087                &|selector| {
2088                    if must_be_nonsimple {
2089                        // Simple selectors are prohibited from appearing in
2090                        // expressions in the lookup argument by
2091                        // `ConstraintSystem`.
2092                        assert!(!selector.is_simple());
2093                    }
2094
2095                    selector_replacements[selector.0].clone()
2096                },
2097                &|query| Expression::Fixed(query),
2098                &|query| Expression::Advice(query),
2099                &|query| Expression::Instance(query),
2100                &|challenge| Expression::Challenge(challenge),
2101                &|a| -a,
2102                &|a, b| a + b,
2103                &|a, b| a * b,
2104                &|a, f| a * f,
2105            );
2106        }
2107
2108        // Substitute selectors for the real fixed columns in all gates
2109        for expr in self.gates.iter_mut().flat_map(|gate| gate.polys.iter_mut()) {
2110            replace_selectors(expr, selector_replacements, false);
2111        }
2112
2113        // Substitute non-simple selectors for the real fixed columns in all
2114        // lookup expressions
2115        for expr in self.lookups.iter_mut().flat_map(|lookup| {
2116            lookup
2117                .input_expressions
2118                .iter_mut()
2119                .chain(lookup.table_expressions.iter_mut())
2120        }) {
2121            replace_selectors(expr, selector_replacements, true);
2122        }
2123    }
2124
2125    /// Allocate a new (simple) selector. Simple selectors cannot be added to
2126    /// expressions nor multiplied by other expressions containing simple
2127    /// selectors. Also, simple selectors may not appear in lookup argument
2128    /// inputs.
2129    pub fn selector(&mut self) -> Selector {
2130        let index = self.num_selectors;
2131        self.num_selectors += 1;
2132        Selector(index, true)
2133    }
2134
2135    /// Allocate a new complex selector that can appear anywhere
2136    /// within expressions.
2137    pub fn complex_selector(&mut self) -> Selector {
2138        let index = self.num_selectors;
2139        self.num_selectors += 1;
2140        Selector(index, false)
2141    }
2142
2143    /// Allocates a new fixed column that can be used in a lookup table.
2144    pub fn lookup_table_column(&mut self) -> TableColumn {
2145        TableColumn {
2146            inner: self.fixed_column(),
2147        }
2148    }
2149
2150    /// Annotate a Lookup column.
2151    pub fn annotate_lookup_column<A, AR>(&mut self, column: TableColumn, annotation: A)
2152    where
2153        A: Fn() -> AR,
2154        AR: Into<String>,
2155    {
2156        // We don't care if the table has already an annotation. If it's the case we keep the new one.
2157        self.general_column_annotations.insert(
2158            metadata::Column::from((Any::Fixed, column.inner().index)),
2159            annotation().into(),
2160        );
2161    }
2162
2163    /// Annotate an Instance column.
2164    pub fn annotate_lookup_any_column<A, AR, T>(&mut self, column: T, annotation: A)
2165    where
2166        A: Fn() -> AR,
2167        AR: Into<String>,
2168        T: Into<Column<Any>>,
2169    {
2170        let col_any = column.into();
2171        // We don't care if the table has already an annotation. If it's the case we keep the new one.
2172        self.general_column_annotations.insert(
2173            metadata::Column::from((col_any.column_type, col_any.index)),
2174            annotation().into(),
2175        );
2176    }
2177
2178    /// Allocate a new fixed column
2179    pub fn fixed_column(&mut self) -> Column<Fixed> {
2180        let tmp = Column {
2181            index: self.num_fixed_columns,
2182            column_type: Fixed,
2183        };
2184        self.num_fixed_columns += 1;
2185        tmp
2186    }
2187
2188    /// Allocate a new advice column at `FirstPhase`
2189    pub fn advice_column(&mut self) -> Column<Advice> {
2190        self.advice_column_in(FirstPhase)
2191    }
2192
2193    /// Allocate a new advice column in given phase
2194    pub fn advice_column_in<P: Phase>(&mut self, phase: P) -> Column<Advice> {
2195        let phase = phase.to_sealed();
2196        if let Some(previous_phase) = phase.prev() {
2197            self.assert_phase_exists(
2198                previous_phase,
2199                format!("Column<Advice> in later phase {:?}", phase).as_str(),
2200            );
2201        }
2202
2203        let tmp = Column {
2204            index: self.num_advice_columns,
2205            column_type: Advice { phase },
2206        };
2207        self.num_advice_columns += 1;
2208        self.num_advice_queries.push(0);
2209        self.advice_column_phase.push(phase);
2210        tmp
2211    }
2212
2213    /// Allocate a new instance column
2214    pub fn instance_column(&mut self) -> Column<Instance> {
2215        let tmp = Column {
2216            index: self.num_instance_columns,
2217            column_type: Instance,
2218        };
2219        self.num_instance_columns += 1;
2220        tmp
2221    }
2222
2223    /// Requests a challenge that is usable after the given phase.
2224    pub fn challenge_usable_after<P: Phase>(&mut self, phase: P) -> Challenge {
2225        let phase = phase.to_sealed();
2226        self.assert_phase_exists(
2227            phase,
2228            format!("Challenge usable after phase {:?}", phase).as_str(),
2229        );
2230
2231        let tmp = Challenge {
2232            index: self.num_challenges,
2233            phase,
2234        };
2235        self.num_challenges += 1;
2236        self.challenge_phase.push(phase);
2237        tmp
2238    }
2239
2240    /// Helper funciotn to assert phase exists, to make sure phase-aware resources
2241    /// are allocated in order, and to avoid any phase to be skipped accidentally
2242    /// to cause unexpected issue in the future.
2243    fn assert_phase_exists(&self, phase: sealed::Phase, resource: &str) {
2244        self.advice_column_phase
2245            .iter()
2246            .find(|advice_column_phase| **advice_column_phase == phase)
2247            .unwrap_or_else(|| {
2248                panic!(
2249                    "No Column<Advice> is used in phase {:?} while allocating a new {:?}",
2250                    phase, resource
2251                )
2252            });
2253    }
2254
2255    pub(crate) fn phases(&self) -> impl Iterator<Item = sealed::Phase> {
2256        let max_phase = self
2257            .advice_column_phase
2258            .iter()
2259            .max()
2260            .map(|phase| phase.0)
2261            .unwrap_or_default();
2262        (0..=max_phase).map(sealed::Phase)
2263    }
2264
2265    /// Compute the degree of the constraint system (the maximum degree of all
2266    /// constraints).
2267    pub fn degree(&self) -> usize {
2268        // The permutation argument will serve alongside the gates, so must be
2269        // accounted for.
2270        let mut degree = self.permutation.required_degree();
2271
2272        // The lookup argument also serves alongside the gates and must be accounted
2273        // for.
2274        degree = std::cmp::max(
2275            degree,
2276            self.lookups
2277                .iter()
2278                .map(|l| l.required_degree())
2279                .max()
2280                .unwrap_or(1),
2281        );
2282
2283        // Account for each gate to ensure our quotient polynomial is the
2284        // correct degree and that our extended domain is the right size.
2285        degree = std::cmp::max(
2286            degree,
2287            self.gates
2288                .iter()
2289                .flat_map(|gate| gate.polynomials().iter().map(|poly| poly.degree()))
2290                .max()
2291                .unwrap_or(0),
2292        );
2293
2294        fn get_max_degree() -> usize {
2295            var("MAX_DEGREE")
2296                .unwrap_or_else(|_| "5".to_string())
2297                .parse()
2298                .expect("Cannot parse MAX_DEGREE env var as usize")
2299        }
2300        degree = std::cmp::min(degree, get_max_degree());
2301
2302        std::cmp::max(degree, self.minimum_degree.unwrap_or(1))
2303    }
2304
2305    /// Compute the number of blinding factors necessary to perfectly blind
2306    /// each of the prover's witness polynomials.
2307    pub fn blinding_factors(&self) -> usize {
2308        // All of the prover's advice columns are evaluated at no more than
2309        let factors = *self.num_advice_queries.iter().max().unwrap_or(&1);
2310        // distinct points during gate checks.
2311
2312        // - The permutation argument witness polynomials are evaluated at most 3 times.
2313        // - Each lookup argument has independent witness polynomials, and they are
2314        //   evaluated at most 2 times.
2315        let factors = std::cmp::max(3, factors);
2316
2317        // Each polynomial is evaluated at most an additional time during
2318        // multiopen (at x_3 to produce q_evals):
2319        let factors = factors + 1;
2320
2321        // h(x) is derived by the other evaluations so it does not reveal
2322        // anything; in fact it does not even appear in the proof.
2323
2324        // h(x_3) is also not revealed; the verifier only learns a single
2325        // evaluation of a polynomial in x_1 which has h(x_3) and another random
2326        // polynomial evaluated at x_3 as coefficients -- this random polynomial
2327        // is "random_poly" in the vanishing argument.
2328
2329        // Add an additional blinding factor as a slight defense against
2330        // off-by-one errors.
2331        factors + 1
2332    }
2333
2334    /// Returns the minimum necessary rows that need to exist in order to
2335    /// account for e.g. blinding factors.
2336    pub fn minimum_rows(&self) -> usize {
2337        self.blinding_factors() // m blinding factors
2338            + 1 // for l_{-(m + 1)} (l_last)
2339            + 1 // for l_0 (just for extra breathing room for the permutation
2340                // argument, to essentially force a separation in the
2341                // permutation polynomial between the roles of l_last, l_0
2342                // and the interstitial values.)
2343            + 1 // for at least one row
2344    }
2345
2346    /// Returns number of fixed columns
2347    pub fn num_fixed_columns(&self) -> usize {
2348        self.num_fixed_columns
2349    }
2350
2351    /// Returns number of advice columns
2352    pub fn num_advice_columns(&self) -> usize {
2353        self.num_advice_columns
2354    }
2355
2356    /// Returns number of instance columns
2357    pub fn num_instance_columns(&self) -> usize {
2358        self.num_instance_columns
2359    }
2360
2361    /// Returns number of selectors
2362    pub fn num_selectors(&self) -> usize {
2363        self.num_selectors
2364    }
2365
2366    /// Returns number of challenges
2367    pub fn num_challenges(&self) -> usize {
2368        self.num_challenges
2369    }
2370
2371    /// Returns phase of advice columns
2372    pub fn advice_column_phase(&self) -> Vec<u8> {
2373        self.advice_column_phase
2374            .iter()
2375            .map(|phase| phase.0)
2376            .collect()
2377    }
2378
2379    /// Returns phase of challenges
2380    pub fn challenge_phase(&self) -> Vec<u8> {
2381        self.challenge_phase.iter().map(|phase| phase.0).collect()
2382    }
2383
2384    /// Returns gates
2385    pub fn gates(&self) -> &Vec<Gate<F>> {
2386        &self.gates
2387    }
2388
2389    /// Returns general column annotations
2390    pub fn general_column_annotations(&self) -> &HashMap<metadata::Column, String> {
2391        &self.general_column_annotations
2392    }
2393
2394    /// Returns advice queries
2395    pub fn advice_queries(&self) -> &Vec<(Column<Advice>, Rotation)> {
2396        &self.advice_queries
2397    }
2398
2399    /// Returns instance queries
2400    pub fn instance_queries(&self) -> &Vec<(Column<Instance>, Rotation)> {
2401        &self.instance_queries
2402    }
2403
2404    /// Returns fixed queries
2405    pub fn fixed_queries(&self) -> &Vec<(Column<Fixed>, Rotation)> {
2406        &self.fixed_queries
2407    }
2408
2409    /// Returns permutation argument
2410    pub fn permutation(&self) -> &permutation::Argument {
2411        &self.permutation
2412    }
2413
2414    /// Returns lookup arguments
2415    pub fn lookups(&self) -> &Vec<lookup::Argument<F>> {
2416        &self.lookups
2417    }
2418
2419    /// Returns constants
2420    pub fn constants(&self) -> &Vec<Column<Fixed>> {
2421        &self.constants
2422    }
2423}
2424
2425/// Exposes the "virtual cells" that can be queried while creating a custom gate or lookup
2426/// table.
2427#[derive(Debug)]
2428pub struct VirtualCells<'a, F: Field> {
2429    meta: &'a mut ConstraintSystem<F>,
2430    queried_selectors: Vec<Selector>,
2431    queried_cells: Vec<VirtualCell>,
2432}
2433
2434impl<'a, F: Field> VirtualCells<'a, F> {
2435    fn new(meta: &'a mut ConstraintSystem<F>) -> Self {
2436        VirtualCells {
2437            meta,
2438            queried_selectors: vec![],
2439            queried_cells: vec![],
2440        }
2441    }
2442
2443    /// Query a selector at the current position.
2444    pub fn query_selector(&mut self, selector: Selector) -> Expression<F> {
2445        self.queried_selectors.push(selector);
2446        Expression::Selector(selector)
2447    }
2448
2449    /// Query a fixed column at a relative position
2450    pub fn query_fixed(&mut self, column: Column<Fixed>, at: Rotation) -> Expression<F> {
2451        self.queried_cells.push((column, at).into());
2452        Expression::Fixed(FixedQuery {
2453            index: Some(self.meta.query_fixed_index(column, at)),
2454            column_index: column.index,
2455            rotation: at,
2456        })
2457    }
2458
2459    /// Query an advice column at a relative position
2460    pub fn query_advice(&mut self, column: Column<Advice>, at: Rotation) -> Expression<F> {
2461        self.queried_cells.push((column, at).into());
2462        Expression::Advice(AdviceQuery {
2463            index: Some(self.meta.query_advice_index(column, at)),
2464            column_index: column.index,
2465            rotation: at,
2466            phase: column.column_type().phase,
2467        })
2468    }
2469
2470    /// Query an instance column at a relative position
2471    pub fn query_instance(&mut self, column: Column<Instance>, at: Rotation) -> Expression<F> {
2472        self.queried_cells.push((column, at).into());
2473        Expression::Instance(InstanceQuery {
2474            index: Some(self.meta.query_instance_index(column, at)),
2475            column_index: column.index,
2476            rotation: at,
2477        })
2478    }
2479
2480    /// Query an Any column at a relative position
2481    pub fn query_any<C: Into<Column<Any>>>(&mut self, column: C, at: Rotation) -> Expression<F> {
2482        let column = column.into();
2483        match column.column_type() {
2484            Any::Advice(_) => self.query_advice(Column::<Advice>::try_from(column).unwrap(), at),
2485            Any::Fixed => self.query_fixed(Column::<Fixed>::try_from(column).unwrap(), at),
2486            Any::Instance => self.query_instance(Column::<Instance>::try_from(column).unwrap(), at),
2487        }
2488    }
2489
2490    /// Query a challenge
2491    pub fn query_challenge(&mut self, challenge: Challenge) -> Expression<F> {
2492        Expression::Challenge(challenge)
2493    }
2494}