snarkvm_circuit_environment/helpers/
r1cs.rs1use crate::{
17 helpers::{Constraint, Counter},
18 prelude::*,
19};
20use snarkvm_fields::PrimeField;
21
22use std::rc::Rc;
23
24pub type Scope = String;
25
26#[derive(Debug)]
27pub struct R1CS<F: PrimeField> {
28 constants: Vec<Variable<F>>,
29 public: Vec<Variable<F>>,
30 private: Vec<Variable<F>>,
31 constraints: Vec<Rc<Constraint<F>>>,
32 counter: Counter<F>,
33 num_variables: u64,
34 nonzeros: (u64, u64, u64),
35}
36
37impl<F: PrimeField> R1CS<F> {
38 pub(crate) fn new() -> Self {
40 Self {
41 constants: Default::default(),
42 public: vec![Variable::Public(Rc::new((0u64, F::one())))],
43 private: Default::default(),
44 constraints: Default::default(),
45 counter: Default::default(),
46 num_variables: 1u64,
47 nonzeros: (0, 0, 0),
48 }
49 }
50
51 pub(crate) fn push_scope<S: Into<String>>(&mut self, name: S) -> Result<(), String> {
53 self.counter.push(name)
54 }
55
56 pub(crate) fn pop_scope<S: Into<String>>(&mut self, name: S) -> Result<(), String> {
58 self.counter.pop(name)
59 }
60
61 pub(crate) fn new_constant(&mut self, value: F) -> Variable<F> {
63 let variable = Variable::Constant(Rc::new(value));
64 self.constants.push(variable.clone());
65 self.counter.increment_constant();
66 self.num_variables += 1;
67 variable
68 }
69
70 pub(crate) fn new_public(&mut self, value: F) -> Variable<F> {
72 let variable = Variable::Public(Rc::new((self.public.len() as u64, value)));
73 self.public.push(variable.clone());
74 self.counter.increment_public();
75 self.num_variables += 1;
76 variable
77 }
78
79 pub(crate) fn new_private(&mut self, value: F) -> Variable<F> {
81 let variable = Variable::Private(Rc::new((self.private.len() as u64, value)));
82 self.private.push(variable.clone());
83 self.counter.increment_private();
84 self.num_variables += 1;
85 variable
86 }
87
88 pub(crate) fn enforce(&mut self, constraint: Constraint<F>) {
90 let (a_nonzeros, b_nonzeros, c_nonzeros) = constraint.num_nonzeros();
91 self.nonzeros.0 += a_nonzeros;
92 self.nonzeros.1 += b_nonzeros;
93 self.nonzeros.2 += c_nonzeros;
94
95 let constraint = Rc::new(constraint);
96 self.constraints.push(Rc::clone(&constraint));
97 self.counter.add_constraint(constraint);
98 }
99
100 pub fn is_satisfied(&self) -> bool {
105 let constraints_satisfied = self.constraints.iter().all(|constraint| constraint.is_satisfied());
107 if !constraints_satisfied {
108 return false;
109 }
110
111 #[cfg(not(debug_assertions))]
113 return true;
114 #[cfg(debug_assertions)]
115 self.constraints.iter().all(|constraint| {
116 let (a, b, c) = constraint.to_terms();
117 [a, b, c].into_iter().all(|lc| {
118 lc.to_terms().iter().all(|(variable, _)| match variable {
119 Variable::Constant(_value) => false, Variable::Private(private) => {
121 let (index, value) = private.as_ref();
122 self.private.get(*index as usize).map_or_else(|| false, |v| v.value() == *value)
123 }
124 Variable::Public(public) => {
125 let (index, value) = public.as_ref();
126 self.public.get(*index as usize).map_or_else(|| false, |v| v.value() == *value)
127 }
128 })
129 })
130 })
131 }
132
133 pub(crate) fn is_satisfied_in_scope(&self) -> bool {
135 self.counter.is_satisfied_in_scope()
136 }
137
138 pub(crate) fn scope(&self) -> Scope {
140 self.counter.scope()
141 }
142
143 pub fn num_constants(&self) -> u64 {
145 self.constants.len() as u64
146 }
147
148 pub fn num_public(&self) -> u64 {
150 self.public.len() as u64
151 }
152
153 pub fn num_private(&self) -> u64 {
155 self.private.len() as u64
156 }
157
158 pub fn num_variables(&self) -> u64 {
160 self.num_variables
161 }
162
163 pub fn num_constraints(&self) -> u64 {
165 self.constraints.len() as u64
166 }
167
168 pub fn num_nonzeros(&self) -> (u64, u64, u64) {
170 self.nonzeros
171 }
172
173 pub(crate) fn num_constants_in_scope(&self) -> u64 {
175 self.counter.num_constants_in_scope()
176 }
177
178 pub(crate) fn num_public_in_scope(&self) -> u64 {
180 self.counter.num_public_in_scope()
181 }
182
183 pub(crate) fn num_private_in_scope(&self) -> u64 {
185 self.counter.num_private_in_scope()
186 }
187
188 pub(crate) fn num_constraints_in_scope(&self) -> u64 {
190 self.counter.num_constraints_in_scope()
191 }
192
193 pub(crate) fn num_nonzeros_in_scope(&self) -> (u64, u64, u64) {
195 self.counter.num_nonzeros_in_scope()
196 }
197
198 pub fn to_public_variables(&self) -> &Vec<Variable<F>> {
200 &self.public
201 }
202
203 pub fn to_private_variables(&self) -> &Vec<Variable<F>> {
205 &self.private
206 }
207
208 pub fn to_constraints(&self) -> &Vec<Rc<Constraint<F>>> {
210 &self.constraints
211 }
212}
213
214impl<F: PrimeField> Display for R1CS<F> {
215 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
216 let mut output = String::default();
217 for constraint in self.to_constraints() {
218 output += &constraint.to_string();
219 }
220 output += "\n";
221
222 write!(f, "{output}")
223 }
224}