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