arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
ark-r1cs-std/src/boolean/not.rs
src/boolean/not.rsRaw
 1use ark_ff::Field;
 2use ark_relations::r1cs::SynthesisError;
 3use ark_std::ops::Not;
 4
 5use super::Boolean;
 6
 7impl<F: Field> Boolean<F> {
 8    fn _not(&self) -> Result<Self, SynthesisError> {
 9        match *self {
10            Boolean::Constant(c) => Ok(Boolean::Constant(!c)),
11            Boolean::Var(ref v) => Ok(Boolean::Var(v.not().unwrap())),
12        }
13    }
14}
15
16impl<'a, F: Field> Not for &'a Boolean<F> {
17    type Output = Boolean<F>;
18    /// Negates `self`.
19    ///
20    /// This *does not* create any new variables or constraints.
21    /// ```
22    /// # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
23    /// // We'll use the BLS12-381 scalar field for our constraints.
24    /// use ark_test_curves::bls12_381::Fr;
25    /// use ark_relations::r1cs::*;
26    /// use ark_r1cs_std::prelude::*;
27    ///
28    /// let cs = ConstraintSystem::<Fr>::new_ref();
29    ///
30    /// let a = Boolean::new_witness(cs.clone(), || Ok(true))?;
31    /// let b = Boolean::new_witness(cs.clone(), || Ok(false))?;
32    ///
33    /// (!&a).enforce_equal(&b)?;
34    /// (!&b).enforce_equal(&a)?;
35    ///
36    /// (!&a).enforce_equal(&Boolean::FALSE)?;
37    /// (!&b).enforce_equal(&Boolean::TRUE)?;
38    ///
39    /// assert!(cs.is_satisfied().unwrap());
40    /// # Ok(())
41    /// # }
42    /// ```
43    #[tracing::instrument(target = "r1cs", skip(self))]
44    fn not(self) -> Self::Output {
45        self._not().unwrap()
46    }
47}
48
49impl<'a, F: Field> Not for &'a mut Boolean<F> {
50    type Output = Boolean<F>;
51
52    #[tracing::instrument(target = "r1cs", skip(self))]
53    fn not(self) -> Self::Output {
54        self._not().unwrap()
55    }
56}
57
58impl<F: Field> Not for Boolean<F> {
59    type Output = Boolean<F>;
60
61    #[tracing::instrument(target = "r1cs", skip(self))]
62    fn not(self) -> Self::Output {
63        self._not().unwrap()
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70    use crate::{
71        alloc::{AllocVar, AllocationMode},
72        boolean::test_utils::run_unary_exhaustive,
73        prelude::EqGadget,
74        R1CSVar,
75    };
76    use ark_test_curves::bls12_381::Fr;
77
78    #[test]
79    fn not() {
80        run_unary_exhaustive::<Fr>(|a| {
81            let cs = a.cs();
82            let computed = !&a;
83            let expected_mode = if a.is_constant() {
84                AllocationMode::Constant
85            } else {
86                AllocationMode::Witness
87            };
88            let expected = Boolean::new_variable(cs.clone(), || Ok(!a.value()?), expected_mode)?;
89            assert_eq!(expected.value(), computed.value());
90            expected.enforce_equal(&computed)?;
91            if !a.is_constant() {
92                assert!(cs.is_satisfied().unwrap());
93            }
94            Ok(())
95        })
96        .unwrap()
97    }
98}