1use core::cmp::max;
2use core::ops::{Add, Mul};
3use ff::Field;
4use std::{
5 convert::TryFrom,
6 ops::{Neg, Sub},
7};
8
9use super::{lookup, permutation, Assigned, Error};
10use crate::circuit::Layouter;
11use crate::{circuit::Region, poly::Rotation};
12
13mod compress_selectors;
14
15pub trait ColumnType:
17 'static + Sized + Copy + std::fmt::Debug + PartialEq + Eq + Into<Any>
18{
19}
20
21#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
23pub struct Column<C: ColumnType> {
24 index: usize,
25 column_type: C,
26}
27
28impl<C: ColumnType> Column<C> {
29 #[cfg(test)]
30 pub(crate) fn new(index: usize, column_type: C) -> Self {
31 Column { index, column_type }
32 }
33
34 pub(crate) fn index(&self) -> usize {
35 self.index
36 }
37
38 pub fn column_type(&self) -> &C {
40 &self.column_type
41 }
42}
43
44impl<C: ColumnType> Ord for Column<C> {
45 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
46 match self.column_type.into().cmp(&other.column_type.into()) {
49 std::cmp::Ordering::Equal => self.index.cmp(&other.index),
51 order => order,
52 }
53 }
54}
55
56impl<C: ColumnType> PartialOrd for Column<C> {
57 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
58 Some(self.cmp(other))
59 }
60}
61
62#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
64pub struct Advice;
65
66#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
68pub struct Fixed;
69
70#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
72pub struct Instance;
73
74#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
76pub enum Any {
77 Advice,
79 Fixed,
81 Instance,
83}
84
85impl Ord for Any {
86 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
87 match (self, other) {
90 (Any::Instance, Any::Instance)
91 | (Any::Advice, Any::Advice)
92 | (Any::Fixed, Any::Fixed) => std::cmp::Ordering::Equal,
93 (Any::Instance, Any::Advice)
95 | (Any::Advice, Any::Fixed)
96 | (Any::Instance, Any::Fixed) => std::cmp::Ordering::Less,
97 (Any::Fixed, Any::Instance)
98 | (Any::Fixed, Any::Advice)
99 | (Any::Advice, Any::Instance) => std::cmp::Ordering::Greater,
100 }
101 }
102}
103
104impl PartialOrd for Any {
105 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
106 Some(self.cmp(other))
107 }
108}
109
110impl ColumnType for Advice {}
111impl ColumnType for Fixed {}
112impl ColumnType for Instance {}
113impl ColumnType for Any {}
114
115impl From<Advice> for Any {
116 fn from(_: Advice) -> Any {
117 Any::Advice
118 }
119}
120
121impl From<Fixed> for Any {
122 fn from(_: Fixed) -> Any {
123 Any::Fixed
124 }
125}
126
127impl From<Instance> for Any {
128 fn from(_: Instance) -> Any {
129 Any::Instance
130 }
131}
132
133impl From<Column<Advice>> for Column<Any> {
134 fn from(advice: Column<Advice>) -> Column<Any> {
135 Column {
136 index: advice.index(),
137 column_type: Any::Advice,
138 }
139 }
140}
141
142impl From<Column<Fixed>> for Column<Any> {
143 fn from(advice: Column<Fixed>) -> Column<Any> {
144 Column {
145 index: advice.index(),
146 column_type: Any::Fixed,
147 }
148 }
149}
150
151impl From<Column<Instance>> for Column<Any> {
152 fn from(advice: Column<Instance>) -> Column<Any> {
153 Column {
154 index: advice.index(),
155 column_type: Any::Instance,
156 }
157 }
158}
159
160impl TryFrom<Column<Any>> for Column<Advice> {
161 type Error = &'static str;
162
163 fn try_from(any: Column<Any>) -> Result<Self, Self::Error> {
164 match any.column_type() {
165 Any::Advice => Ok(Column {
166 index: any.index(),
167 column_type: Advice,
168 }),
169 _ => Err("Cannot convert into Column<Advice>"),
170 }
171 }
172}
173
174impl TryFrom<Column<Any>> for Column<Fixed> {
175 type Error = &'static str;
176
177 fn try_from(any: Column<Any>) -> Result<Self, Self::Error> {
178 match any.column_type() {
179 Any::Fixed => Ok(Column {
180 index: any.index(),
181 column_type: Fixed,
182 }),
183 _ => Err("Cannot convert into Column<Fixed>"),
184 }
185 }
186}
187
188impl TryFrom<Column<Any>> for Column<Instance> {
189 type Error = &'static str;
190
191 fn try_from(any: Column<Any>) -> Result<Self, Self::Error> {
192 match any.column_type() {
193 Any::Instance => Ok(Column {
194 index: any.index(),
195 column_type: Instance,
196 }),
197 _ => Err("Cannot convert into Column<Instance>"),
198 }
199 }
200}
201
202#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
251pub struct Selector(pub(crate) usize, bool);
252
253impl Selector {
254 pub fn enable<F: Field>(&self, region: &mut Region<F>, offset: usize) -> Result<(), Error> {
256 region.enable_selector(|| "", self, offset)
257 }
258
259 pub fn is_simple(&self) -> bool {
262 self.1
263 }
264}
265
266#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
277pub struct TableColumn {
278 inner: Column<Fixed>,
286}
287
288impl TableColumn {
289 pub(crate) fn inner(&self) -> Column<Fixed> {
290 self.inner
291 }
292}
293
294pub trait Assignment<F: Field> {
297 fn enter_region<NR, N>(&mut self, name_fn: N)
305 where
306 NR: Into<String>,
307 N: FnOnce() -> NR;
308
309 fn exit_region(&mut self);
317
318 fn enable_selector<A, AR>(
320 &mut self,
321 annotation: A,
322 selector: &Selector,
323 row: usize,
324 ) -> Result<(), Error>
325 where
326 A: FnOnce() -> AR,
327 AR: Into<String>;
328
329 fn query_instance(&self, column: Column<Instance>, row: usize) -> Result<Option<F>, Error>;
333
334 fn assign_advice<V, VR, A, AR>(
336 &mut self,
337 annotation: A,
338 column: Column<Advice>,
339 row: usize,
340 to: V,
341 ) -> Result<(), Error>
342 where
343 V: FnOnce() -> Result<VR, Error>,
344 VR: Into<Assigned<F>>,
345 A: FnOnce() -> AR,
346 AR: Into<String>;
347
348 fn assign_fixed<V, VR, A, AR>(
350 &mut self,
351 annotation: A,
352 column: Column<Fixed>,
353 row: usize,
354 to: V,
355 ) -> Result<(), Error>
356 where
357 V: FnOnce() -> Result<VR, Error>,
358 VR: Into<Assigned<F>>,
359 A: FnOnce() -> AR,
360 AR: Into<String>;
361
362 fn copy(
364 &mut self,
365 left_column: Column<Any>,
366 left_row: usize,
367 right_column: Column<Any>,
368 right_row: usize,
369 ) -> Result<(), Error>;
370
371 fn fill_from_row(
373 &mut self,
374 column: Column<Fixed>,
375 row: usize,
376 to: Option<Assigned<F>>,
377 ) -> Result<(), Error>;
378
379 fn push_namespace<NR, N>(&mut self, name_fn: N)
385 where
386 NR: Into<String>,
387 N: FnOnce() -> NR;
388
389 fn pop_namespace(&mut self, gadget_name: Option<String>);
395}
396
397pub trait FloorPlanner {
402 fn synthesize<F: Field, CS: Assignment<F>, C: Circuit<F>>(
413 cs: &mut CS,
414 circuit: &C,
415 config: C::Config,
416 constants: Vec<Column<Fixed>>,
417 ) -> Result<(), Error>;
418}
419
420pub trait Circuit<F: Field> {
424 type Config: Clone;
426 type FloorPlanner: FloorPlanner;
429
430 fn without_witnesses(&self) -> Self;
433
434 fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config;
437
438 fn synthesize(&self, config: Self::Config, layouter: impl Layouter<F>) -> Result<(), Error>;
442}
443
444#[derive(Clone, Debug)]
446pub enum Expression<F> {
447 Constant(F),
449 Selector(Selector),
451 Fixed {
453 query_index: usize,
455 column_index: usize,
457 rotation: Rotation,
459 },
460 Advice {
462 query_index: usize,
464 column_index: usize,
466 rotation: Rotation,
468 },
469 Instance {
471 query_index: usize,
473 column_index: usize,
475 rotation: Rotation,
477 },
478 Negated(Box<Expression<F>>),
480 Sum(Box<Expression<F>>, Box<Expression<F>>),
482 Product(Box<Expression<F>>, Box<Expression<F>>),
484 Scaled(Box<Expression<F>>, F),
486}
487
488impl<F: Field> Expression<F> {
489 pub fn evaluate<T>(
492 &self,
493 constant: &impl Fn(F) -> T,
494 selector_column: &impl Fn(Selector) -> T,
495 fixed_column: &impl Fn(usize, usize, Rotation) -> T,
496 advice_column: &impl Fn(usize, usize, Rotation) -> T,
497 instance_column: &impl Fn(usize, usize, Rotation) -> T,
498 negated: &impl Fn(T) -> T,
499 sum: &impl Fn(T, T) -> T,
500 product: &impl Fn(T, T) -> T,
501 scaled: &impl Fn(T, F) -> T,
502 ) -> T {
503 match self {
504 Expression::Constant(scalar) => constant(*scalar),
505 Expression::Selector(selector) => selector_column(*selector),
506 Expression::Fixed {
507 query_index,
508 column_index,
509 rotation,
510 } => fixed_column(*query_index, *column_index, *rotation),
511 Expression::Advice {
512 query_index,
513 column_index,
514 rotation,
515 } => advice_column(*query_index, *column_index, *rotation),
516 Expression::Instance {
517 query_index,
518 column_index,
519 rotation,
520 } => instance_column(*query_index, *column_index, *rotation),
521 Expression::Negated(a) => {
522 let a = a.evaluate(
523 constant,
524 selector_column,
525 fixed_column,
526 advice_column,
527 instance_column,
528 negated,
529 sum,
530 product,
531 scaled,
532 );
533 negated(a)
534 }
535 Expression::Sum(a, b) => {
536 let a = a.evaluate(
537 constant,
538 selector_column,
539 fixed_column,
540 advice_column,
541 instance_column,
542 negated,
543 sum,
544 product,
545 scaled,
546 );
547 let b = b.evaluate(
548 constant,
549 selector_column,
550 fixed_column,
551 advice_column,
552 instance_column,
553 negated,
554 sum,
555 product,
556 scaled,
557 );
558 sum(a, b)
559 }
560 Expression::Product(a, b) => {
561 let a = a.evaluate(
562 constant,
563 selector_column,
564 fixed_column,
565 advice_column,
566 instance_column,
567 negated,
568 sum,
569 product,
570 scaled,
571 );
572 let b = b.evaluate(
573 constant,
574 selector_column,
575 fixed_column,
576 advice_column,
577 instance_column,
578 negated,
579 sum,
580 product,
581 scaled,
582 );
583 product(a, b)
584 }
585 Expression::Scaled(a, f) => {
586 let a = a.evaluate(
587 constant,
588 selector_column,
589 fixed_column,
590 advice_column,
591 instance_column,
592 negated,
593 sum,
594 product,
595 scaled,
596 );
597 scaled(a, *f)
598 }
599 }
600 }
601
602 pub fn degree(&self) -> usize {
604 match self {
605 Expression::Constant(_) => 0,
606 Expression::Selector(_) => 1,
607 Expression::Fixed { .. } => 1,
608 Expression::Advice { .. } => 1,
609 Expression::Instance { .. } => 1,
610 Expression::Negated(poly) => poly.degree(),
611 Expression::Sum(a, b) => max(a.degree(), b.degree()),
612 Expression::Product(a, b) => a.degree() + b.degree(),
613 Expression::Scaled(poly, _) => poly.degree(),
614 }
615 }
616
617 pub fn square(self) -> Self {
619 self.clone() * self
620 }
621
622 fn contains_simple_selector(&self) -> bool {
624 self.evaluate(
625 &|_| false,
626 &|selector| selector.is_simple(),
627 &|_, _, _| false,
628 &|_, _, _| false,
629 &|_, _, _| false,
630 &|a| a,
631 &|a, b| a || b,
632 &|a, b| a || b,
633 &|a, _| a,
634 )
635 }
636
637 fn extract_simple_selector(&self) -> Option<Selector> {
639 let op = |a, b| match (a, b) {
640 (Some(a), None) | (None, Some(a)) => Some(a),
641 (Some(_), Some(_)) => panic!("two simple selectors cannot be in the same expression"),
642 _ => None,
643 };
644
645 self.evaluate(
646 &|_| None,
647 &|selector| {
648 if selector.is_simple() {
649 Some(selector)
650 } else {
651 None
652 }
653 },
654 &|_, _, _| None,
655 &|_, _, _| None,
656 &|_, _, _| None,
657 &|a| a,
658 &op,
659 &op,
660 &|a, _| a,
661 )
662 }
663}
664
665impl<F: Field> Neg for Expression<F> {
666 type Output = Expression<F>;
667 fn neg(self) -> Self::Output {
668 Expression::Negated(Box::new(self))
669 }
670}
671
672impl<F: Field> Add for Expression<F> {
673 type Output = Expression<F>;
674 fn add(self, rhs: Expression<F>) -> Expression<F> {
675 if self.contains_simple_selector() || rhs.contains_simple_selector() {
676 panic!("attempted to use a simple selector in an addition");
677 }
678 Expression::Sum(Box::new(self), Box::new(rhs))
679 }
680}
681
682impl<F: Field> Sub for Expression<F> {
683 type Output = Expression<F>;
684 fn sub(self, rhs: Expression<F>) -> Expression<F> {
685 if self.contains_simple_selector() || rhs.contains_simple_selector() {
686 panic!("attempted to use a simple selector in a subtraction");
687 }
688 Expression::Sum(Box::new(self), Box::new(-rhs))
689 }
690}
691
692impl<F: Field> Mul for Expression<F> {
693 type Output = Expression<F>;
694 fn mul(self, rhs: Expression<F>) -> Expression<F> {
695 if self.contains_simple_selector() && rhs.contains_simple_selector() {
696 panic!("attempted to multiply two expressions containing simple selectors");
697 }
698 Expression::Product(Box::new(self), Box::new(rhs))
699 }
700}
701
702impl<F: Field> Mul<F> for Expression<F> {
703 type Output = Expression<F>;
704 fn mul(self, rhs: F) -> Expression<F> {
705 Expression::Scaled(Box::new(self), rhs)
706 }
707}
708
709#[derive(Copy, Clone, Debug)]
712pub(crate) struct PointIndex(pub usize);
713
714#[derive(Clone, Debug)]
717pub(crate) struct VirtualCell {
718 pub(crate) column: Column<Any>,
719 pub(crate) rotation: Rotation,
720}
721
722impl<Col: Into<Column<Any>>> From<(Col, Rotation)> for VirtualCell {
723 fn from((column, rotation): (Col, Rotation)) -> Self {
724 VirtualCell {
725 column: column.into(),
726 rotation,
727 }
728 }
729}
730
731#[derive(Debug)]
735pub struct Constraint<F: Field> {
736 name: &'static str,
737 poly: Expression<F>,
738}
739
740impl<F: Field> From<Expression<F>> for Constraint<F> {
741 fn from(poly: Expression<F>) -> Self {
742 Constraint { name: "", poly }
743 }
744}
745
746impl<F: Field> From<(&'static str, Expression<F>)> for Constraint<F> {
747 fn from((name, poly): (&'static str, Expression<F>)) -> Self {
748 Constraint { name, poly }
749 }
750}
751
752impl<F: Field> From<Expression<F>> for Vec<Constraint<F>> {
753 fn from(poly: Expression<F>) -> Self {
754 vec![Constraint { name: "", poly }]
755 }
756}
757
758#[derive(Debug)]
793pub struct Constraints<F: Field, C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>> {
794 selector: Expression<F>,
795 constraints: Iter,
796}
797
798impl<F: Field, C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>> Constraints<F, C, Iter> {
799 pub fn with_selector(selector: Expression<F>, constraints: Iter) -> Self {
804 Constraints {
805 selector,
806 constraints,
807 }
808 }
809}
810
811fn apply_selector_to_constraint<F: Field, C: Into<Constraint<F>>>(
812 (selector, c): (Expression<F>, C),
813) -> Constraint<F> {
814 let constraint: Constraint<F> = c.into();
815 Constraint {
816 name: constraint.name,
817 poly: selector * constraint.poly,
818 }
819}
820
821type ApplySelectorToConstraint<F, C> = fn((Expression<F>, C)) -> Constraint<F>;
822type ConstraintsIterator<F, C, I> = std::iter::Map<
823 std::iter::Zip<std::iter::Repeat<Expression<F>>, I>,
824 ApplySelectorToConstraint<F, C>,
825>;
826
827impl<F: Field, C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>> IntoIterator
828 for Constraints<F, C, Iter>
829{
830 type Item = Constraint<F>;
831 type IntoIter = ConstraintsIterator<F, C, Iter::IntoIter>;
832
833 fn into_iter(self) -> Self::IntoIter {
834 std::iter::repeat(self.selector)
835 .zip(self.constraints.into_iter())
836 .map(apply_selector_to_constraint)
837 }
838}
839
840#[derive(Clone, Debug)]
841pub(crate) struct Gate<F: Field> {
842 name: &'static str,
843 constraint_names: Vec<&'static str>,
844 polys: Vec<Expression<F>>,
845 queried_selectors: Vec<Selector>,
848 queried_cells: Vec<VirtualCell>,
849}
850
851impl<F: Field> Gate<F> {
852 pub(crate) fn name(&self) -> &'static str {
853 self.name
854 }
855
856 pub(crate) fn constraint_name(&self, constraint_index: usize) -> &'static str {
857 self.constraint_names[constraint_index]
858 }
859
860 pub(crate) fn polynomials(&self) -> &[Expression<F>] {
861 &self.polys
862 }
863
864 pub(crate) fn queried_selectors(&self) -> &[Selector] {
865 &self.queried_selectors
866 }
867
868 pub(crate) fn queried_cells(&self) -> &[VirtualCell] {
869 &self.queried_cells
870 }
871}
872
873#[derive(Debug, Clone)]
876pub struct ConstraintSystem<F: Field> {
877 pub(crate) num_fixed_columns: usize,
878 pub(crate) num_advice_columns: usize,
879 pub(crate) num_instance_columns: usize,
880 pub(crate) num_selectors: usize,
881
882 pub(crate) selector_map: Vec<Column<Fixed>>,
886
887 pub(crate) gates: Vec<Gate<F>>,
888 pub(crate) advice_queries: Vec<(Column<Advice>, Rotation)>,
889 num_advice_queries: Vec<usize>,
893 pub(crate) instance_queries: Vec<(Column<Instance>, Rotation)>,
894 pub(crate) fixed_queries: Vec<(Column<Fixed>, Rotation)>,
895
896 pub(crate) permutation: permutation::Argument,
898
899 pub(crate) lookups: Vec<lookup::Argument<F>>,
902
903 pub(crate) constants: Vec<Column<Fixed>>,
906
907 pub(crate) minimum_degree: Option<usize>,
908}
909
910#[allow(dead_code)]
912#[derive(Debug)]
913pub struct PinnedConstraintSystem<'a, F: Field> {
914 num_fixed_columns: &'a usize,
915 num_advice_columns: &'a usize,
916 num_instance_columns: &'a usize,
917 num_selectors: &'a usize,
918 gates: PinnedGates<'a, F>,
919 advice_queries: &'a Vec<(Column<Advice>, Rotation)>,
920 instance_queries: &'a Vec<(Column<Instance>, Rotation)>,
921 fixed_queries: &'a Vec<(Column<Fixed>, Rotation)>,
922 permutation: &'a permutation::Argument,
923 lookups: &'a Vec<lookup::Argument<F>>,
924 constants: &'a Vec<Column<Fixed>>,
925 minimum_degree: &'a Option<usize>,
926}
927
928struct PinnedGates<'a, F: Field>(&'a Vec<Gate<F>>);
929
930impl<'a, F: Field> std::fmt::Debug for PinnedGates<'a, F> {
931 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
932 f.debug_list()
933 .entries(self.0.iter().flat_map(|gate| gate.polynomials().iter()))
934 .finish()
935 }
936}
937
938impl<F: Field> Default for ConstraintSystem<F> {
939 fn default() -> ConstraintSystem<F> {
940 ConstraintSystem {
941 num_fixed_columns: 0,
942 num_advice_columns: 0,
943 num_instance_columns: 0,
944 num_selectors: 0,
945 selector_map: vec![],
946 gates: vec![],
947 fixed_queries: Vec::new(),
948 advice_queries: Vec::new(),
949 num_advice_queries: Vec::new(),
950 instance_queries: Vec::new(),
951 permutation: permutation::Argument::new(),
952 lookups: Vec::new(),
953 constants: vec![],
954 minimum_degree: None,
955 }
956 }
957}
958
959impl<F: Field> ConstraintSystem<F> {
960 pub fn pinned(&self) -> PinnedConstraintSystem<'_, F> {
964 PinnedConstraintSystem {
965 num_fixed_columns: &self.num_fixed_columns,
966 num_advice_columns: &self.num_advice_columns,
967 num_instance_columns: &self.num_instance_columns,
968 num_selectors: &self.num_selectors,
969 gates: PinnedGates(&self.gates),
970 fixed_queries: &self.fixed_queries,
971 advice_queries: &self.advice_queries,
972 instance_queries: &self.instance_queries,
973 permutation: &self.permutation,
974 lookups: &self.lookups,
975 constants: &self.constants,
976 minimum_degree: &self.minimum_degree,
977 }
978 }
979
980 pub fn enable_constant(&mut self, column: Column<Fixed>) {
986 if !self.constants.contains(&column) {
987 self.constants.push(column);
988 self.enable_equality(column);
989 }
990 }
991
992 pub fn enable_equality<C: Into<Column<Any>>>(&mut self, column: C) {
994 let column = column.into();
995 self.query_any_index(column, Rotation::cur());
996 self.permutation.add_column(column);
997 }
998
999 pub fn lookup(
1004 &mut self,
1005 table_map: impl FnOnce(&mut VirtualCells<'_, F>) -> Vec<(Expression<F>, TableColumn)>,
1006 ) -> usize {
1007 let mut cells = VirtualCells::new(self);
1008 let table_map = table_map(&mut cells)
1009 .into_iter()
1010 .map(|(input, table)| {
1011 if input.contains_simple_selector() {
1012 panic!("expression containing simple selector supplied to lookup argument");
1013 }
1014
1015 let table = cells.query_fixed(table.inner(), Rotation::cur());
1016
1017 (input, table)
1018 })
1019 .collect();
1020
1021 let index = self.lookups.len();
1022
1023 self.lookups.push(lookup::Argument::new(table_map));
1024
1025 index
1026 }
1027
1028 fn query_fixed_index(&mut self, column: Column<Fixed>, at: Rotation) -> usize {
1029 for (index, fixed_query) in self.fixed_queries.iter().enumerate() {
1031 if fixed_query == &(column, at) {
1032 return index;
1033 }
1034 }
1035
1036 let index = self.fixed_queries.len();
1038 self.fixed_queries.push((column, at));
1039
1040 index
1041 }
1042
1043 pub(crate) fn query_advice_index(&mut self, column: Column<Advice>, at: Rotation) -> usize {
1044 for (index, advice_query) in self.advice_queries.iter().enumerate() {
1046 if advice_query == &(column, at) {
1047 return index;
1048 }
1049 }
1050
1051 let index = self.advice_queries.len();
1053 self.advice_queries.push((column, at));
1054 self.num_advice_queries[column.index] += 1;
1055
1056 index
1057 }
1058
1059 fn query_instance_index(&mut self, column: Column<Instance>, at: Rotation) -> usize {
1060 for (index, instance_query) in self.instance_queries.iter().enumerate() {
1062 if instance_query == &(column, at) {
1063 return index;
1064 }
1065 }
1066
1067 let index = self.instance_queries.len();
1069 self.instance_queries.push((column, at));
1070
1071 index
1072 }
1073
1074 fn query_any_index(&mut self, column: Column<Any>, at: Rotation) -> usize {
1075 match column.column_type() {
1076 Any::Advice => self.query_advice_index(Column::<Advice>::try_from(column).unwrap(), at),
1077 Any::Fixed => self.query_fixed_index(Column::<Fixed>::try_from(column).unwrap(), at),
1078 Any::Instance => {
1079 self.query_instance_index(Column::<Instance>::try_from(column).unwrap(), at)
1080 }
1081 }
1082 }
1083
1084 pub(crate) fn get_advice_query_index(&self, column: Column<Advice>, at: Rotation) -> usize {
1085 for (index, advice_query) in self.advice_queries.iter().enumerate() {
1086 if advice_query == &(column, at) {
1087 return index;
1088 }
1089 }
1090
1091 panic!("get_advice_query_index called for non-existent query");
1092 }
1093
1094 pub(crate) fn get_fixed_query_index(&self, column: Column<Fixed>, at: Rotation) -> usize {
1095 for (index, fixed_query) in self.fixed_queries.iter().enumerate() {
1096 if fixed_query == &(column, at) {
1097 return index;
1098 }
1099 }
1100
1101 panic!("get_fixed_query_index called for non-existent query");
1102 }
1103
1104 pub(crate) fn get_instance_query_index(&self, column: Column<Instance>, at: Rotation) -> usize {
1105 for (index, instance_query) in self.instance_queries.iter().enumerate() {
1106 if instance_query == &(column, at) {
1107 return index;
1108 }
1109 }
1110
1111 panic!("get_instance_query_index called for non-existent query");
1112 }
1113
1114 pub(crate) fn get_any_query_index(&self, column: Column<Any>, at: Rotation) -> usize {
1115 match column.column_type() {
1116 Any::Advice => {
1117 self.get_advice_query_index(Column::<Advice>::try_from(column).unwrap(), at)
1118 }
1119 Any::Fixed => {
1120 self.get_fixed_query_index(Column::<Fixed>::try_from(column).unwrap(), at)
1121 }
1122 Any::Instance => {
1123 self.get_instance_query_index(Column::<Instance>::try_from(column).unwrap(), at)
1124 }
1125 }
1126 }
1127
1128 pub fn set_minimum_degree(&mut self, degree: usize) {
1132 self.minimum_degree = Some(degree);
1133 }
1134
1135 pub fn create_gate<C: Into<Constraint<F>>, Iter: IntoIterator<Item = C>>(
1142 &mut self,
1143 name: &'static str,
1144 constraints: impl FnOnce(&mut VirtualCells<'_, F>) -> Iter,
1145 ) {
1146 let mut cells = VirtualCells::new(self);
1147 let constraints = constraints(&mut cells);
1148 let queried_selectors = cells.queried_selectors;
1149 let queried_cells = cells.queried_cells;
1150
1151 let (constraint_names, polys): (_, Vec<_>) = constraints
1152 .into_iter()
1153 .map(|c| c.into())
1154 .map(|c| (c.name, c.poly))
1155 .unzip();
1156
1157 assert!(
1158 !polys.is_empty(),
1159 "Gates must contain at least one constraint."
1160 );
1161
1162 self.gates.push(Gate {
1163 name,
1164 constraint_names,
1165 polys,
1166 queried_selectors,
1167 queried_cells,
1168 });
1169 }
1170
1171 pub(crate) fn compress_selectors(mut self, selectors: Vec<Vec<bool>>) -> (Self, Vec<Vec<F>>) {
1179 assert_eq!(selectors.len(), self.num_selectors);
1182
1183 let mut degrees = vec![0; selectors.len()];
1188 for expr in self.gates.iter().flat_map(|gate| gate.polys.iter()) {
1189 if let Some(selector) = expr.extract_simple_selector() {
1190 degrees[selector.0] = max(degrees[selector.0], expr.degree());
1191 }
1192 }
1193
1194 let max_degree = self.degree();
1197
1198 let mut new_columns = vec![];
1199 let (polys, selector_assignment) = compress_selectors::process(
1200 selectors
1201 .into_iter()
1202 .zip(degrees.into_iter())
1203 .enumerate()
1204 .map(
1205 |(i, (activations, max_degree))| compress_selectors::SelectorDescription {
1206 selector: i,
1207 activations,
1208 max_degree,
1209 },
1210 )
1211 .collect(),
1212 max_degree,
1213 || {
1214 let column = self.fixed_column();
1215 new_columns.push(column);
1216 Expression::Fixed {
1217 query_index: self.query_fixed_index(column, Rotation::cur()),
1218 column_index: column.index,
1219 rotation: Rotation::cur(),
1220 }
1221 },
1222 );
1223
1224 let mut selector_map = vec![None; selector_assignment.len()];
1225 let mut selector_replacements = vec![None; selector_assignment.len()];
1226 for assignment in selector_assignment {
1227 selector_replacements[assignment.selector] = Some(assignment.expression);
1228 selector_map[assignment.selector] = Some(new_columns[assignment.combination_index]);
1229 }
1230
1231 self.selector_map = selector_map
1232 .into_iter()
1233 .map(|a| a.unwrap())
1234 .collect::<Vec<_>>();
1235 let selector_replacements = selector_replacements
1236 .into_iter()
1237 .map(|a| a.unwrap())
1238 .collect::<Vec<_>>();
1239
1240 fn replace_selectors<F: Field>(
1241 expr: &mut Expression<F>,
1242 selector_replacements: &[Expression<F>],
1243 must_be_nonsimple: bool,
1244 ) {
1245 *expr = expr.evaluate(
1246 &|constant| Expression::Constant(constant),
1247 &|selector| {
1248 if must_be_nonsimple {
1249 assert!(!selector.is_simple());
1253 }
1254
1255 selector_replacements[selector.0].clone()
1256 },
1257 &|query_index, column_index, rotation| Expression::Fixed {
1258 query_index,
1259 column_index,
1260 rotation,
1261 },
1262 &|query_index, column_index, rotation| Expression::Advice {
1263 query_index,
1264 column_index,
1265 rotation,
1266 },
1267 &|query_index, column_index, rotation| Expression::Instance {
1268 query_index,
1269 column_index,
1270 rotation,
1271 },
1272 &|a| -a,
1273 &|a, b| a + b,
1274 &|a, b| a * b,
1275 &|a, f| a * f,
1276 );
1277 }
1278
1279 for expr in self.gates.iter_mut().flat_map(|gate| gate.polys.iter_mut()) {
1281 replace_selectors(expr, &selector_replacements, false);
1282 }
1283
1284 for expr in self.lookups.iter_mut().flat_map(|lookup| {
1287 lookup
1288 .input_expressions
1289 .iter_mut()
1290 .chain(lookup.table_expressions.iter_mut())
1291 }) {
1292 replace_selectors(expr, &selector_replacements, true);
1293 }
1294
1295 (self, polys)
1296 }
1297
1298 pub fn selector(&mut self) -> Selector {
1303 let index = self.num_selectors;
1304 self.num_selectors += 1;
1305 Selector(index, true)
1306 }
1307
1308 pub fn complex_selector(&mut self) -> Selector {
1311 let index = self.num_selectors;
1312 self.num_selectors += 1;
1313 Selector(index, false)
1314 }
1315
1316 pub fn lookup_table_column(&mut self) -> TableColumn {
1318 TableColumn {
1319 inner: self.fixed_column(),
1320 }
1321 }
1322
1323 pub fn fixed_column(&mut self) -> Column<Fixed> {
1325 let tmp = Column {
1326 index: self.num_fixed_columns,
1327 column_type: Fixed,
1328 };
1329 self.num_fixed_columns += 1;
1330 tmp
1331 }
1332
1333 pub fn advice_column(&mut self) -> Column<Advice> {
1335 let tmp = Column {
1336 index: self.num_advice_columns,
1337 column_type: Advice,
1338 };
1339 self.num_advice_columns += 1;
1340 self.num_advice_queries.push(0);
1341 tmp
1342 }
1343
1344 pub fn instance_column(&mut self) -> Column<Instance> {
1346 let tmp = Column {
1347 index: self.num_instance_columns,
1348 column_type: Instance,
1349 };
1350 self.num_instance_columns += 1;
1351 tmp
1352 }
1353
1354 pub fn degree(&self) -> usize {
1357 let mut degree = self.permutation.required_degree();
1360
1361 degree = std::cmp::max(
1364 degree,
1365 self.lookups
1366 .iter()
1367 .map(|l| l.required_degree())
1368 .max()
1369 .unwrap_or(1),
1370 );
1371
1372 degree = std::cmp::max(
1375 degree,
1376 self.gates
1377 .iter()
1378 .flat_map(|gate| gate.polynomials().iter().map(|poly| poly.degree()))
1379 .max()
1380 .unwrap_or(0),
1381 );
1382
1383 std::cmp::max(degree, self.minimum_degree.unwrap_or(1))
1384 }
1385
1386 pub fn blinding_factors(&self) -> usize {
1389 let factors = *self.num_advice_queries.iter().max().unwrap_or(&1);
1391 let factors = std::cmp::max(3, factors);
1397
1398 let factors = factors + 1;
1401
1402 factors + 1
1413 }
1414
1415 pub fn minimum_rows(&self) -> usize {
1418 self.blinding_factors() + 1 + 1 + 1 }
1426}
1427
1428#[derive(Debug)]
1431pub struct VirtualCells<'a, F: Field> {
1432 meta: &'a mut ConstraintSystem<F>,
1433 queried_selectors: Vec<Selector>,
1434 queried_cells: Vec<VirtualCell>,
1435}
1436
1437impl<'a, F: Field> VirtualCells<'a, F> {
1438 fn new(meta: &'a mut ConstraintSystem<F>) -> Self {
1439 VirtualCells {
1440 meta,
1441 queried_selectors: vec![],
1442 queried_cells: vec![],
1443 }
1444 }
1445
1446 pub fn query_selector(&mut self, selector: Selector) -> Expression<F> {
1448 self.queried_selectors.push(selector);
1449 Expression::Selector(selector)
1450 }
1451
1452 pub fn query_fixed(&mut self, column: Column<Fixed>, at: Rotation) -> Expression<F> {
1454 self.queried_cells.push((column, at).into());
1455 Expression::Fixed {
1456 query_index: self.meta.query_fixed_index(column, at),
1457 column_index: column.index,
1458 rotation: at,
1459 }
1460 }
1461
1462 pub fn query_advice(&mut self, column: Column<Advice>, at: Rotation) -> Expression<F> {
1464 self.queried_cells.push((column, at).into());
1465 Expression::Advice {
1466 query_index: self.meta.query_advice_index(column, at),
1467 column_index: column.index,
1468 rotation: at,
1469 }
1470 }
1471
1472 pub fn query_instance(&mut self, column: Column<Instance>, at: Rotation) -> Expression<F> {
1474 self.queried_cells.push((column, at).into());
1475 Expression::Instance {
1476 query_index: self.meta.query_instance_index(column, at),
1477 column_index: column.index,
1478 rotation: at,
1479 }
1480 }
1481
1482 pub fn query_any<C: Into<Column<Any>>>(&mut self, column: C, at: Rotation) -> Expression<F> {
1484 let column = column.into();
1485 match column.column_type() {
1486 Any::Advice => self.query_advice(Column::<Advice>::try_from(column).unwrap(), at),
1487 Any::Fixed => self.query_fixed(Column::<Fixed>::try_from(column).unwrap(), at),
1488 Any::Instance => self.query_instance(Column::<Instance>::try_from(column).unwrap(), at),
1489 }
1490 }
1491}