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
23pub trait ColumnType:
25 'static + Sized + Copy + std::fmt::Debug + PartialEq + Eq + Into<Any>
26{
27 fn query_cell<F: Field>(&self, index: usize, at: Rotation) -> Expression<F>;
29}
30
31#[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 pub fn index(&self) -> usize {
46 self.index
47 }
48
49 pub fn column_type(&self) -> &C {
51 &self.column_type
52 }
53
54 pub fn query_cell<F: Field>(&self, at: Rotation) -> Expression<F> {
56 self.column_type.query_cell(self.index, at)
57 }
58
59 pub fn cur<F: Field>(&self) -> Expression<F> {
61 self.query_cell(Rotation::cur())
62 }
63
64 pub fn next<F: Field>(&self) -> Expression<F> {
66 self.query_cell(Rotation::next())
67 }
68
69 pub fn prev<F: Field>(&self) -> Expression<F> {
71 self.query_cell(Rotation::prev())
72 }
73
74 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 match self.column_type.into().cmp(&other.column_type.into()) {
85 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 #[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 pub trait SealedPhase {
126 fn to_sealed(self) -> Phase;
127 }
128}
129
130pub trait Phase: SealedPhase {}
132
133impl<P: SealedPhase> Phase for P {}
134
135#[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#[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#[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#[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 pub fn new<P: Phase>(phase: P) -> Advice {
182 Advice {
183 phase: phase.to_sealed(),
184 }
185 }
186
187 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 if self.phase != FirstPhase.to_sealed() {
198 debug_struct.field("phase", &self.phase);
199 }
200 debug_struct.finish()
201 }
202}
203
204#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
206pub struct Fixed;
207
208#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
210pub struct Instance;
211
212#[derive(Clone, Copy, Eq, PartialEq, Hash)]
214pub enum Any {
215 Advice(Advice),
217 Fixed,
219 Instance,
221}
222
223impl Any {
224 pub fn advice() -> Any {
226 Any::Advice(Advice::default())
227 }
228
229 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 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 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 (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#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
466pub struct Selector(pub(crate) usize, bool);
467
468impl Selector {
469 pub fn enable<F: Field>(&self, region: &mut Region<F>, offset: usize) -> Result<(), Error> {
471 region.enable_selector(|| "", self, offset)
472 }
473
474 pub fn is_simple(&self) -> bool {
477 self.1
478 }
479
480 pub fn index(&self) -> usize {
482 self.0
483 }
484
485 pub fn expr<F: Field>(&self) -> Expression<F> {
487 Expression::Selector(*self)
488 }
489}
490
491#[derive(Copy, Clone, Debug)]
493pub struct FixedQuery {
494 pub(crate) index: Option<usize>,
496 pub(crate) column_index: usize,
498 pub(crate) rotation: Rotation,
500}
501
502impl FixedQuery {
503 pub fn column_index(&self) -> usize {
505 self.column_index
506 }
507
508 pub fn rotation(&self) -> Rotation {
510 self.rotation
511 }
512}
513
514#[derive(Copy, Clone, Debug)]
516pub struct AdviceQuery {
517 pub(crate) index: Option<usize>,
519 pub(crate) column_index: usize,
521 pub(crate) rotation: Rotation,
523 pub(crate) phase: sealed::Phase,
525}
526
527impl AdviceQuery {
528 pub fn column_index(&self) -> usize {
530 self.column_index
531 }
532
533 pub fn rotation(&self) -> Rotation {
535 self.rotation
536 }
537
538 pub fn phase(&self) -> u8 {
540 self.phase.0
541 }
542}
543
544#[derive(Copy, Clone, Debug)]
546pub struct InstanceQuery {
547 pub(crate) index: Option<usize>,
549 pub(crate) column_index: usize,
551 pub(crate) rotation: Rotation,
553}
554
555impl InstanceQuery {
556 pub fn column_index(&self) -> usize {
558 self.column_index
559 }
560
561 pub fn rotation(&self) -> Rotation {
563 self.rotation
564 }
565}
566
567#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
578pub struct TableColumn {
579 inner: Column<Fixed>,
587}
588
589impl TableColumn {
590 pub fn inner(&self) -> Column<Fixed> {
592 self.inner
593 }
594}
595
596#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
598pub struct Challenge {
599 index: usize,
600 pub(crate) phase: sealed::Phase,
601}
602
603impl Challenge {
604 pub fn index(&self) -> usize {
606 self.index
607 }
608
609 pub fn phase(&self) -> u8 {
611 self.phase.0
612 }
613
614 pub fn expr<F: Field>(&self) -> Expression<F> {
616 Expression::Challenge(*self)
617 }
618}
619
620pub trait Assignment<F: Field> {
623 fn enter_region<NR, N>(&mut self, name_fn: N)
631 where
632 NR: Into<String>,
633 N: FnOnce() -> NR;
634
635 fn annotate_column<A, AR>(&mut self, annotation: A, column: Column<Any>)
639 where
640 A: FnOnce() -> AR,
641 AR: Into<String>;
642
643 fn exit_region(&mut self);
651
652 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 fn query_instance(&self, column: Column<Instance>, row: usize) -> Result<Value<F>, Error>;
667
668 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 fn assign_fixed(&mut self, column: Column<Fixed>, row: usize, to: Assigned<F>);
678
679 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 fn fill_from_row(
690 &mut self,
691 column: Column<Fixed>,
692 row: usize,
693 to: Value<Assigned<F>>,
694 ) -> Result<(), Error>;
695
696 fn get_challenge(&self, challenge: Challenge) -> Value<F>;
700
701 fn push_namespace<NR, N>(&mut self, name_fn: N)
707 where
708 NR: Into<String>,
709 N: FnOnce() -> NR;
710
711 fn pop_namespace(&mut self, gadget_name: Option<String>);
717
718 fn next_phase(&mut self) {}
721}
722
723pub trait FloorPlanner {
728 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
746pub trait Circuit<F: Field> {
750 type Config: Clone;
752 type FloorPlanner: FloorPlanner;
755 #[cfg(feature = "circuit-params")]
757 type Params: Default;
758
759 fn without_witnesses(&self) -> Self;
762
763 #[cfg(feature = "circuit-params")]
766 fn params(&self) -> Self::Params {
767 Self::Params::default()
768 }
769
770 #[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 fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config;
785
786 fn synthesize(&self, config: Self::Config, layouter: impl Layouter<F>) -> Result<(), Error>;
790}
791
792#[derive(Clone)]
794pub enum Expression<F> {
795 Constant(F),
797 Selector(Selector),
799 Fixed(FixedQuery),
801 Advice(AdviceQuery),
803 Instance(InstanceQuery),
805 Challenge(Challenge),
807 Negated(Box<Expression<F>>),
809 Sum(Box<Expression<F>>, Box<Expression<F>>),
811 Product(Box<Expression<F>>, Box<Expression<F>>),
813 Scaled(Box<Expression<F>>, F),
815}
816
817impl<F: Field> Expression<F> {
818 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 #[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 #[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 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 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 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 pub fn square(self) -> Self {
1205 self.clone() * self
1206 }
1207
1208 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 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 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 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 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 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 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#[derive(Copy, Clone, Debug)]
1422pub(crate) struct PointIndex(pub usize);
1423
1424#[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#[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#[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 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#[derive(Clone, Debug)]
1562pub struct Gate<F: Field> {
1563 name: String,
1564 constraint_names: Vec<String>,
1565 polys: Vec<Expression<F>>,
1566 queried_selectors: Vec<Selector>,
1569 queried_cells: Vec<VirtualCell>,
1570}
1571
1572impl<F: Field> Gate<F> {
1573 pub fn name(&self) -> &str {
1575 self.name.as_str()
1576 }
1577
1578 pub fn constraint_name(&self, constraint_index: usize) -> &str {
1580 self.constraint_names[constraint_index].as_str()
1581 }
1582
1583 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#[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 pub(crate) advice_column_phase: Vec<sealed::Phase>,
1609 pub(crate) challenge_phase: Vec<sealed::Phase>,
1611
1612 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 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 pub(crate) permutation: permutation::Argument,
1628
1629 pub(crate) lookups: Vec<lookup::Argument<F>>,
1632
1633 pub(crate) general_column_annotations: HashMap<metadata::Column, String>,
1635
1636 pub(crate) constants: Vec<Column<Fixed>>,
1639
1640 pub(crate) minimum_degree: Option<usize>,
1641}
1642
1643#[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 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 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 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 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 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 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 for (index, fixed_query) in self.fixed_queries.iter().enumerate() {
1828 if fixed_query == &(column, at) {
1829 return index;
1830 }
1831 }
1832
1833 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 for (index, advice_query) in self.advice_queries.iter().enumerate() {
1843 if advice_query == &(column, at) {
1844 return index;
1845 }
1846 }
1847
1848 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 for (index, instance_query) in self.instance_queries.iter().enumerate() {
1859 if instance_query == &(column, at) {
1860 return index;
1861 }
1862 }
1863
1864 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 pub fn set_minimum_degree(&mut self, degree: usize) {
1931 self.minimum_degree = Some(degree);
1932 }
1933
1934 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 pub fn compress_selectors(mut self, selectors: Vec<Vec<bool>>) -> (Self, Vec<Vec<F>>) {
1981 assert_eq!(selectors.len(), self.num_selectors);
1984
1985 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 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 pub fn directly_convert_selectors_to_fixed(
2048 mut self,
2049 selectors: Vec<Vec<bool>>,
2050 ) -> (Self, Vec<Vec<F>>) {
2051 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 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 for expr in self.gates.iter_mut().flat_map(|gate| gate.polys.iter_mut()) {
2110 replace_selectors(expr, selector_replacements, false);
2111 }
2112
2113 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 pub fn selector(&mut self) -> Selector {
2130 let index = self.num_selectors;
2131 self.num_selectors += 1;
2132 Selector(index, true)
2133 }
2134
2135 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 pub fn lookup_table_column(&mut self) -> TableColumn {
2145 TableColumn {
2146 inner: self.fixed_column(),
2147 }
2148 }
2149
2150 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 self.general_column_annotations.insert(
2158 metadata::Column::from((Any::Fixed, column.inner().index)),
2159 annotation().into(),
2160 );
2161 }
2162
2163 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 self.general_column_annotations.insert(
2173 metadata::Column::from((col_any.column_type, col_any.index)),
2174 annotation().into(),
2175 );
2176 }
2177
2178 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 pub fn advice_column(&mut self) -> Column<Advice> {
2190 self.advice_column_in(FirstPhase)
2191 }
2192
2193 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 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 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 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 pub fn degree(&self) -> usize {
2268 let mut degree = self.permutation.required_degree();
2271
2272 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 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 pub fn blinding_factors(&self) -> usize {
2308 let factors = *self.num_advice_queries.iter().max().unwrap_or(&1);
2310 let factors = std::cmp::max(3, factors);
2316
2317 let factors = factors + 1;
2320
2321 factors + 1
2332 }
2333
2334 pub fn minimum_rows(&self) -> usize {
2337 self.blinding_factors() + 1 + 1 + 1 }
2345
2346 pub fn num_fixed_columns(&self) -> usize {
2348 self.num_fixed_columns
2349 }
2350
2351 pub fn num_advice_columns(&self) -> usize {
2353 self.num_advice_columns
2354 }
2355
2356 pub fn num_instance_columns(&self) -> usize {
2358 self.num_instance_columns
2359 }
2360
2361 pub fn num_selectors(&self) -> usize {
2363 self.num_selectors
2364 }
2365
2366 pub fn num_challenges(&self) -> usize {
2368 self.num_challenges
2369 }
2370
2371 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 pub fn challenge_phase(&self) -> Vec<u8> {
2381 self.challenge_phase.iter().map(|phase| phase.0).collect()
2382 }
2383
2384 pub fn gates(&self) -> &Vec<Gate<F>> {
2386 &self.gates
2387 }
2388
2389 pub fn general_column_annotations(&self) -> &HashMap<metadata::Column, String> {
2391 &self.general_column_annotations
2392 }
2393
2394 pub fn advice_queries(&self) -> &Vec<(Column<Advice>, Rotation)> {
2396 &self.advice_queries
2397 }
2398
2399 pub fn instance_queries(&self) -> &Vec<(Column<Instance>, Rotation)> {
2401 &self.instance_queries
2402 }
2403
2404 pub fn fixed_queries(&self) -> &Vec<(Column<Fixed>, Rotation)> {
2406 &self.fixed_queries
2407 }
2408
2409 pub fn permutation(&self) -> &permutation::Argument {
2411 &self.permutation
2412 }
2413
2414 pub fn lookups(&self) -> &Vec<lookup::Argument<F>> {
2416 &self.lookups
2417 }
2418
2419 pub fn constants(&self) -> &Vec<Column<Fixed>> {
2421 &self.constants
2422 }
2423}
2424
2425#[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 pub fn query_selector(&mut self, selector: Selector) -> Expression<F> {
2445 self.queried_selectors.push(selector);
2446 Expression::Selector(selector)
2447 }
2448
2449 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 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 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 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 pub fn query_challenge(&mut self, challenge: Challenge) -> Expression<F> {
2492 Expression::Challenge(challenge)
2493 }
2494}