snarkvm_algorithms/r1cs/
constraint_system.rs1use crate::r1cs::{Index, LinearCombination, Namespace, Variable, errors::SynthesisError};
17use snarkvm_fields::Field;
18
19use std::marker::PhantomData;
20
21pub trait ConstraintSynthesizer<F: Field>: Sync {
25 fn generate_constraints<CS: ConstraintSystem<F>>(&self, cs: &mut CS) -> Result<(), SynthesisError>;
27}
28
29pub trait ConstraintSystem<F: Field>: Sized {
32 type Root: ConstraintSystem<F>;
35
36 fn one() -> Variable {
38 Variable::new_unchecked(Index::Public(0))
39 }
40
41 fn alloc<FN, A, AR>(&mut self, annotation: A, f: FN) -> Result<Variable, SynthesisError>
46 where
47 FN: FnOnce() -> Result<F, SynthesisError>,
48 A: FnOnce() -> AR,
49 AR: AsRef<str>;
50
51 fn alloc_input<FN, A, AR>(&mut self, annotation: A, f: FN) -> Result<Variable, SynthesisError>
54 where
55 FN: FnOnce() -> Result<F, SynthesisError>,
56 A: FnOnce() -> AR,
57 AR: AsRef<str>;
58
59 fn enforce<A, AR, LA, LB, LC>(&mut self, annotation: A, a: LA, b: LB, c: LC)
63 where
64 A: FnOnce() -> AR,
65 AR: AsRef<str>,
66 LA: FnOnce(LinearCombination<F>) -> LinearCombination<F>,
67 LB: FnOnce(LinearCombination<F>) -> LinearCombination<F>,
68 LC: FnOnce(LinearCombination<F>) -> LinearCombination<F>;
69
70 fn push_namespace<NR, N>(&mut self, name_fn: N)
73 where
74 NR: AsRef<str>,
75 N: FnOnce() -> NR;
76
77 fn pop_namespace(&mut self);
80
81 fn get_root(&mut self) -> &mut Self::Root;
84
85 fn ns<NR, N>(&mut self, name_fn: N) -> Namespace<'_, F, Self::Root>
87 where
88 NR: AsRef<str>,
89 N: FnOnce() -> NR,
90 {
91 self.get_root().push_namespace(name_fn);
92
93 Namespace(self.get_root(), PhantomData)
94 }
95
96 fn num_constraints(&self) -> usize;
98
99 fn num_public_variables(&self) -> usize;
101
102 fn num_private_variables(&self) -> usize;
104
105 fn is_in_setup_mode(&self) -> bool;
107}
108
109impl<F: Field, CS: ConstraintSystem<F>> ConstraintSystem<F> for &mut CS {
112 type Root = CS::Root;
113
114 #[inline]
115 fn one() -> Variable {
116 CS::one()
117 }
118
119 #[inline]
120 fn alloc<FN, A, AR>(&mut self, annotation: A, f: FN) -> Result<Variable, SynthesisError>
121 where
122 FN: FnOnce() -> Result<F, SynthesisError>,
123 A: FnOnce() -> AR,
124 AR: AsRef<str>,
125 {
126 (**self).alloc(annotation, f)
127 }
128
129 #[inline]
130 fn alloc_input<FN, A, AR>(&mut self, annotation: A, f: FN) -> Result<Variable, SynthesisError>
131 where
132 FN: FnOnce() -> Result<F, SynthesisError>,
133 A: FnOnce() -> AR,
134 AR: AsRef<str>,
135 {
136 (**self).alloc_input(annotation, f)
137 }
138
139 #[inline]
140 fn enforce<A, AR, LA, LB, LC>(&mut self, annotation: A, a: LA, b: LB, c: LC)
141 where
142 A: FnOnce() -> AR,
143 AR: AsRef<str>,
144 LA: FnOnce(LinearCombination<F>) -> LinearCombination<F>,
145 LB: FnOnce(LinearCombination<F>) -> LinearCombination<F>,
146 LC: FnOnce(LinearCombination<F>) -> LinearCombination<F>,
147 {
148 (**self).enforce(annotation, a, b, c)
149 }
150
151 #[inline]
152 fn push_namespace<NR, N>(&mut self, name_fn: N)
153 where
154 NR: AsRef<str>,
155 N: FnOnce() -> NR,
156 {
157 (**self).push_namespace(name_fn)
158 }
159
160 #[inline]
161 fn pop_namespace(&mut self) {
162 (**self).pop_namespace()
163 }
164
165 #[inline]
166 fn get_root(&mut self) -> &mut Self::Root {
167 (**self).get_root()
168 }
169
170 #[inline]
171 fn num_constraints(&self) -> usize {
172 (**self).num_constraints()
173 }
174
175 #[inline]
176 fn num_public_variables(&self) -> usize {
177 (**self).num_public_variables()
178 }
179
180 #[inline]
181 fn num_private_variables(&self) -> usize {
182 (**self).num_private_variables()
183 }
184
185 #[inline]
186 fn is_in_setup_mode(&self) -> bool {
187 (**self).is_in_setup_mode()
188 }
189}