ark_r1cs_std/boolean/
not.rs1use ark_ff::Field;
2use ark_relations::gr1cs::SynthesisError;
3use ark_std::ops::Not;
4
5use super::Boolean;
6
7impl<F: Field> Boolean<F> {
8 fn _not(&self) -> Result<Self, SynthesisError> {
9 let mut result = self.clone();
10 result.not_in_place()?;
11 Ok(result)
12 }
13
14 pub fn not_in_place(&mut self) -> Result<(), SynthesisError> {
16 match *self {
17 Boolean::Constant(ref mut c) => *c = !*c,
18 Boolean::Var(ref mut v) => *v = v.not()?,
19 }
20 Ok(())
21 }
22}
23
24impl<'a, F: Field> Not for &'a Boolean<F> {
25 type Output = Boolean<F>;
26 #[tracing::instrument(target = "gr1cs", skip(self))]
52 fn not(self) -> Self::Output {
53 self._not().unwrap()
54 }
55}
56
57impl<'a, F: Field> Not for &'a mut Boolean<F> {
58 type Output = Boolean<F>;
59
60 #[tracing::instrument(target = "gr1cs", skip(self))]
61 fn not(self) -> Self::Output {
62 self._not().unwrap()
63 }
64}
65
66impl<F: Field> Not for Boolean<F> {
67 type Output = Boolean<F>;
68
69 #[tracing::instrument(target = "gr1cs", skip(self))]
70 fn not(self) -> Self::Output {
71 self._not().unwrap()
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use crate::{
79 alloc::{AllocVar, AllocationMode},
80 boolean::test_utils::run_unary_exhaustive,
81 prelude::EqGadget,
82 GR1CSVar,
83 };
84 use ark_test_curves::bls12_381::Fr;
85
86 #[test]
87 fn not() {
88 run_unary_exhaustive::<Fr>(|a| {
89 let cs = a.cs();
90 let computed = !&a;
91 let expected_mode = if a.is_constant() {
92 AllocationMode::Constant
93 } else {
94 AllocationMode::Witness
95 };
96 let expected = Boolean::new_variable(cs.clone(), || Ok(!a.value()?), expected_mode)?;
97 assert_eq!(expected.value(), computed.value());
98 expected.enforce_equal(&computed)?;
99 if !a.is_constant() {
100 assert!(cs.is_satisfied().unwrap());
101 }
102 Ok(())
103 })
104 .unwrap()
105 }
106}