/ circuit / types / boolean / src / nor.rs
nor.rs
  1  // Copyright (c) 2025 ADnet Contributors
  2  // This file is part of the AlphaVM library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  use super::*;
 17  
 18  impl<E: Environment> Nor<Self> for Boolean<E> {
 19      type Output = Boolean<E>;
 20  
 21      /// Returns `(NOT a) AND (NOT b)`.
 22      fn nor(&self, other: &Self) -> Self::Output {
 23          // Constant `self`
 24          if self.is_constant() {
 25              match self.eject_value() {
 26                  true => !self.clone(),
 27                  false => !other.clone(),
 28              }
 29          }
 30          // Constant `other`
 31          else if other.is_constant() {
 32              match other.eject_value() {
 33                  true => !other.clone(),
 34                  false => !self.clone(),
 35              }
 36          }
 37          // Variable NOR Variable
 38          else {
 39              // Declare a new variable with the expected output as witness.
 40              // Note: The constraint below will ensure `output` is either 0 or 1,
 41              // assuming `self` and `other` are well-formed (they are either 0 or 1).
 42              let output = Boolean(
 43                  E::new_variable(
 44                      Mode::Private,
 45                      match !self.eject_value() & !other.eject_value() {
 46                          true => E::BaseField::one(),
 47                          false => E::BaseField::zero(),
 48                      },
 49                  )
 50                  .into(),
 51              );
 52  
 53              // Ensure (1 - `self`) * (1 - `other`) = `output`
 54              // `output` is `1` iff `self` and `other` are both `0`, otherwise `output` is `0`.
 55              E::enforce(|| (E::one() - &self.0, E::one() - &other.0, &output));
 56  
 57              output
 58          }
 59      }
 60  }
 61  
 62  impl<E: Environment> Metrics<dyn Nor<Boolean<E>, Output = Boolean<E>>> for Boolean<E> {
 63      type Case = (Mode, Mode);
 64  
 65      fn count(case: &Self::Case) -> Count {
 66          match case.0.is_constant() || case.1.is_constant() {
 67              true => Count::is(0, 0, 0, 0),
 68              false => Count::is(0, 0, 1, 1),
 69          }
 70      }
 71  }
 72  
 73  impl<E: Environment> OutputMode<dyn Nor<Boolean<E>, Output = Boolean<E>>> for Boolean<E> {
 74      type Case = (CircuitType<Boolean<E>>, CircuitType<Boolean<E>>);
 75  
 76      fn output_mode(case: &Self::Case) -> Mode {
 77          match (case.0.mode(), case.1.mode()) {
 78              (Mode::Constant, Mode::Constant) => Mode::Constant,
 79              (_, Mode::Constant) => match &case.1 {
 80                  CircuitType::Constant(constant) => match constant.eject_value() {
 81                      true => Mode::Constant,
 82                      false => Mode::Private,
 83                  },
 84                  _ => E::halt("The constant is required to determine the output mode of Public NOR Constant"),
 85              },
 86              (Mode::Constant, _) => match &case.0 {
 87                  CircuitType::Constant(constant) => match constant.eject_value() {
 88                      true => Mode::Constant,
 89                      false => Mode::Private,
 90                  },
 91                  _ => E::halt("The constant is required to determine the output mode of Constant NOR Public"),
 92              },
 93              (_, _) => Mode::Private,
 94          }
 95      }
 96  }
 97  
 98  #[cfg(test)]
 99  mod tests {
100      use super::*;
101      use alphavm_circuit_environment::Circuit;
102  
103      fn check_nor(name: &str, expected: bool, a: Boolean<Circuit>, b: Boolean<Circuit>) {
104          Circuit::scope(name, || {
105              let candidate = a.nor(&b);
106              assert_eq!(expected, candidate.eject_value(), "({} NOR {})", a.eject_value(), b.eject_value());
107              assert_count!(Nor(Boolean, Boolean) => Boolean, &(a.eject_mode(), b.eject_mode()));
108              assert_output_mode!(Nor(Boolean, Boolean) => Boolean, &(CircuitType::from(&a), CircuitType::from(&b)), candidate);
109          });
110          Circuit::reset();
111      }
112  
113      #[test]
114      fn test_constant_nor_constant() {
115          // false NOR false
116          let expected = true;
117          let a = Boolean::<Circuit>::new(Mode::Constant, false);
118          let b = Boolean::<Circuit>::new(Mode::Constant, false);
119          check_nor("false NOR false", expected, a, b);
120  
121          // false NOR true
122          let expected = false;
123          let a = Boolean::<Circuit>::new(Mode::Constant, false);
124          let b = Boolean::<Circuit>::new(Mode::Constant, true);
125          check_nor("false NOR true", expected, a, b);
126  
127          // true NOR false
128          let expected = false;
129          let a = Boolean::<Circuit>::new(Mode::Constant, true);
130          let b = Boolean::<Circuit>::new(Mode::Constant, false);
131          check_nor("true NOR false", expected, a, b);
132  
133          // true NOR true
134          let expected = false;
135          let a = Boolean::<Circuit>::new(Mode::Constant, true);
136          let b = Boolean::<Circuit>::new(Mode::Constant, true);
137          check_nor("true NOR true", expected, a, b);
138      }
139  
140      #[test]
141      fn test_constant_nor_public() {
142          // false NOR false
143          let expected = true;
144          let a = Boolean::<Circuit>::new(Mode::Constant, false);
145          let b = Boolean::<Circuit>::new(Mode::Public, false);
146          check_nor("false NOR false", expected, a, b);
147  
148          // false NOR true
149          let expected = false;
150          let a = Boolean::<Circuit>::new(Mode::Constant, false);
151          let b = Boolean::<Circuit>::new(Mode::Public, true);
152          check_nor("false NOR true", expected, a, b);
153  
154          // true NOR false
155          let expected = false;
156          let a = Boolean::<Circuit>::new(Mode::Constant, true);
157          let b = Boolean::<Circuit>::new(Mode::Public, false);
158          check_nor("true NOR false", expected, a, b);
159  
160          // true NOR true
161          let expected = false;
162          let a = Boolean::<Circuit>::new(Mode::Constant, true);
163          let b = Boolean::<Circuit>::new(Mode::Public, true);
164          check_nor("true NOR true", expected, a, b);
165      }
166  
167      #[test]
168      fn test_constant_nor_private() {
169          // false NOR false
170          let expected = true;
171          let a = Boolean::<Circuit>::new(Mode::Constant, false);
172          let b = Boolean::<Circuit>::new(Mode::Private, false);
173          check_nor("false NOR false", expected, a, b);
174  
175          // false NOR true
176          let expected = false;
177          let a = Boolean::<Circuit>::new(Mode::Constant, false);
178          let b = Boolean::<Circuit>::new(Mode::Private, true);
179          check_nor("false NOR true", expected, a, b);
180  
181          // true NOR false
182          let expected = false;
183          let a = Boolean::<Circuit>::new(Mode::Constant, true);
184          let b = Boolean::<Circuit>::new(Mode::Private, false);
185          check_nor("true NOR false", expected, a, b);
186  
187          // true NOR true
188          let expected = false;
189          let a = Boolean::<Circuit>::new(Mode::Constant, true);
190          let b = Boolean::<Circuit>::new(Mode::Private, true);
191          check_nor("true NOR true", expected, a, b);
192      }
193  
194      #[test]
195      fn test_public_nor_constant() {
196          // false NOR false
197          let expected = true;
198          let a = Boolean::<Circuit>::new(Mode::Public, false);
199          let b = Boolean::<Circuit>::new(Mode::Constant, false);
200          check_nor("false NOR false", expected, a, b);
201  
202          // false NOR true
203          let expected = false;
204          let a = Boolean::<Circuit>::new(Mode::Public, false);
205          let b = Boolean::<Circuit>::new(Mode::Constant, true);
206          check_nor("false NOR true", expected, a, b);
207  
208          // true NOR false
209          let expected = false;
210          let a = Boolean::<Circuit>::new(Mode::Public, true);
211          let b = Boolean::<Circuit>::new(Mode::Constant, false);
212          check_nor("true NOR false", expected, a, b);
213  
214          // true NOR true
215          let expected = false;
216          let a = Boolean::<Circuit>::new(Mode::Public, true);
217          let b = Boolean::<Circuit>::new(Mode::Constant, true);
218          check_nor("true NOR true", expected, a, b);
219      }
220  
221      #[test]
222      fn test_public_nor_public() {
223          // false NOR false
224          let expected = true;
225          let a = Boolean::<Circuit>::new(Mode::Public, false);
226          let b = Boolean::<Circuit>::new(Mode::Public, false);
227          check_nor("false NOR false", expected, a, b);
228  
229          // false NOR true
230          let expected = false;
231          let a = Boolean::<Circuit>::new(Mode::Public, false);
232          let b = Boolean::<Circuit>::new(Mode::Public, true);
233          check_nor("false NOR true", expected, a, b);
234  
235          // true NOR false
236          let expected = false;
237          let a = Boolean::<Circuit>::new(Mode::Public, true);
238          let b = Boolean::<Circuit>::new(Mode::Public, false);
239          check_nor("true NOR false", expected, a, b);
240  
241          // true NOR true
242          let expected = false;
243          let a = Boolean::<Circuit>::new(Mode::Public, true);
244          let b = Boolean::<Circuit>::new(Mode::Public, true);
245          check_nor("true NOR true", expected, a, b);
246      }
247  
248      #[test]
249      fn test_public_nor_private() {
250          // false NOR false
251          let expected = true;
252          let a = Boolean::<Circuit>::new(Mode::Public, false);
253          let b = Boolean::<Circuit>::new(Mode::Private, false);
254          check_nor("false NOR false", expected, a, b);
255  
256          // false NOR true
257          let expected = false;
258          let a = Boolean::<Circuit>::new(Mode::Public, false);
259          let b = Boolean::<Circuit>::new(Mode::Private, true);
260          check_nor("false NOR true", expected, a, b);
261  
262          // true NOR false
263          let expected = false;
264          let a = Boolean::<Circuit>::new(Mode::Public, true);
265          let b = Boolean::<Circuit>::new(Mode::Private, false);
266          check_nor("true NOR false", expected, a, b);
267  
268          // true NOR true
269          let expected = false;
270          let a = Boolean::<Circuit>::new(Mode::Public, true);
271          let b = Boolean::<Circuit>::new(Mode::Private, true);
272          check_nor("true NOR true", expected, a, b);
273      }
274  
275      #[test]
276      fn test_private_nor_constant() {
277          // false NOR false
278          let expected = true;
279          let a = Boolean::<Circuit>::new(Mode::Private, false);
280          let b = Boolean::<Circuit>::new(Mode::Constant, false);
281          check_nor("false NOR false", expected, a, b);
282  
283          // false NOR true
284          let expected = false;
285          let a = Boolean::<Circuit>::new(Mode::Private, false);
286          let b = Boolean::<Circuit>::new(Mode::Constant, true);
287          check_nor("false NOR true", expected, a, b);
288  
289          // true NOR false
290          let expected = false;
291          let a = Boolean::<Circuit>::new(Mode::Private, true);
292          let b = Boolean::<Circuit>::new(Mode::Constant, false);
293          check_nor("true NOR false", expected, a, b);
294  
295          // true NOR true
296          let expected = false;
297          let a = Boolean::<Circuit>::new(Mode::Private, true);
298          let b = Boolean::<Circuit>::new(Mode::Constant, true);
299          check_nor("true NOR true", expected, a, b);
300      }
301  
302      #[test]
303      fn test_private_nor_public() {
304          // false NOR false
305          let expected = true;
306          let a = Boolean::<Circuit>::new(Mode::Private, false);
307          let b = Boolean::<Circuit>::new(Mode::Public, false);
308          check_nor("false NOR false", expected, a, b);
309  
310          // false NOR true
311          let expected = false;
312          let a = Boolean::<Circuit>::new(Mode::Private, false);
313          let b = Boolean::<Circuit>::new(Mode::Public, true);
314          check_nor("false NOR true", expected, a, b);
315  
316          // true NOR false
317          let expected = false;
318          let a = Boolean::<Circuit>::new(Mode::Private, true);
319          let b = Boolean::<Circuit>::new(Mode::Public, false);
320          check_nor("true NOR false", expected, a, b);
321  
322          // true NOR true
323          let expected = false;
324          let a = Boolean::<Circuit>::new(Mode::Private, true);
325          let b = Boolean::<Circuit>::new(Mode::Public, true);
326          check_nor("true NOR true", expected, a, b);
327      }
328  
329      #[test]
330      fn test_private_nor_private() {
331          // false NOR false
332          let expected = true;
333          let a = Boolean::<Circuit>::new(Mode::Private, false);
334          let b = Boolean::<Circuit>::new(Mode::Private, false);
335          check_nor("false NOR false", expected, a, b);
336  
337          // false NOR true
338          let expected = false;
339          let a = Boolean::<Circuit>::new(Mode::Private, false);
340          let b = Boolean::<Circuit>::new(Mode::Private, true);
341          check_nor("false NOR true", expected, a, b);
342  
343          // true NOR false
344          let expected = false;
345          let a = Boolean::<Circuit>::new(Mode::Private, true);
346          let b = Boolean::<Circuit>::new(Mode::Private, false);
347          check_nor("true NOR false", expected, a, b);
348  
349          // true NOR true
350          let expected = false;
351          let a = Boolean::<Circuit>::new(Mode::Private, true);
352          let b = Boolean::<Circuit>::new(Mode::Private, true);
353          check_nor("true NOR true", expected, a, b);
354      }
355  }