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;
102
103 fn num_private_variables(&self) -> usize;
105
106 fn is_in_setup_mode(&self) -> bool;
108}
109
110impl<F: Field, CS: ConstraintSystem<F>> ConstraintSystem<F> for &mut CS {
113 type Root = CS::Root;
114
115 #[inline]
116 fn one() -> Variable {
117 CS::one()
118 }
119
120 #[inline]
121 fn alloc<FN, A, AR>(&mut self, annotation: A, f: FN) -> Result<Variable, SynthesisError>
122 where
123 FN: FnOnce() -> Result<F, SynthesisError>,
124 A: FnOnce() -> AR,
125 AR: AsRef<str>,
126 {
127 (**self).alloc(annotation, f)
128 }
129
130 #[inline]
131 fn alloc_input<FN, A, AR>(&mut self, annotation: A, f: FN) -> Result<Variable, SynthesisError>
132 where
133 FN: FnOnce() -> Result<F, SynthesisError>,
134 A: FnOnce() -> AR,
135 AR: AsRef<str>,
136 {
137 (**self).alloc_input(annotation, f)
138 }
139
140 #[inline]
141 fn enforce<A, AR, LA, LB, LC>(&mut self, annotation: A, a: LA, b: LB, c: LC)
142 where
143 A: FnOnce() -> AR,
144 AR: AsRef<str>,
145 LA: FnOnce(LinearCombination<F>) -> LinearCombination<F>,
146 LB: FnOnce(LinearCombination<F>) -> LinearCombination<F>,
147 LC: FnOnce(LinearCombination<F>) -> LinearCombination<F>,
148 {
149 (**self).enforce(annotation, a, b, c)
150 }
151
152 #[inline]
153 fn push_namespace<NR, N>(&mut self, name_fn: N)
154 where
155 NR: AsRef<str>,
156 N: FnOnce() -> NR,
157 {
158 (**self).push_namespace(name_fn)
159 }
160
161 #[inline]
162 fn pop_namespace(&mut self) {
163 (**self).pop_namespace()
164 }
165
166 #[inline]
167 fn get_root(&mut self) -> &mut Self::Root {
168 (**self).get_root()
169 }
170
171 #[inline]
172 fn num_constraints(&self) -> usize {
173 (**self).num_constraints()
174 }
175
176 #[inline]
177 fn num_public_variables(&self) -> usize {
178 (**self).num_public_variables()
179 }
180
181 #[inline]
182 fn num_private_variables(&self) -> usize {
183 (**self).num_private_variables()
184 }
185
186 #[inline]
187 fn is_in_setup_mode(&self) -> bool {
188 (**self).is_in_setup_mode()
189 }
190}