Skip to content

Commit

Permalink
feat: add Not trait to stdlib (#4999)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves <!-- Link to GitHub Issue -->

## Summary\*

This PR adds a `Not` trait which is an equivalent of Rust's
`std::ops::Not` trait which represents a bitwise NOT.

## Additional Context



## Documentation\*

Check one:
- [ ] No documentation needed.
- [x] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
  • Loading branch information
TomAFrench committed May 8, 2024
1 parent f01d309 commit 95d4d13
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
9 changes: 9 additions & 0 deletions docs/docs/noir/standard_library/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,15 @@ impl Rem for i64 { fn rem(self, other: i64) -> i64 { self % other } }
Implementations:
#include_code neg-trait-impls noir_stdlib/src/ops/arith.nr rust

### `std::ops::Not`

#include_code not-trait noir_stdlib/src/ops/bit.nr rust

`Not::not` is equivalent to the unary bitwise NOT operator `!`.

Implementations:
#include_code not-trait-impls noir_stdlib/src/ops/bit.nr rust

### `std::ops::{ BitOr, BitAnd, BitXor }`

#include_code bitor-trait noir_stdlib/src/ops/bit.nr rust
Expand Down
2 changes: 1 addition & 1 deletion noir_stdlib/src/ops.nr
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ mod arith;
mod bit;

use arith::{Add, Sub, Mul, Div, Rem, Neg};
use bit::{BitOr, BitAnd, BitXor, Shl, Shr};
use bit::{Not, BitOr, BitAnd, BitXor, Shl, Shr};
21 changes: 21 additions & 0 deletions noir_stdlib/src/ops/bit.nr
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
// docs:start:not-trait
trait Not {
fn not(self: Self) -> Self;
}
// docs:end:not-trait

// docs:start:not-trait-impls
impl Not for bool { fn not(self) -> bool { !self } }

impl Not for u64 { fn not(self) -> u64 { !self } }
impl Not for u32 { fn not(self) -> u32 { !self } }
impl Not for u16 { fn not(self) -> u16 { !self } }
impl Not for u8 { fn not(self) -> u8 { !self } }
impl Not for u1 { fn not(self) -> u1 { !self } }

impl Not for i8 { fn not(self) -> i8 { !self } }
impl Not for i16 { fn not(self) -> i16 { !self } }
impl Not for i32 { fn not(self) -> i32 { !self } }
impl Not for i64 { fn not(self) -> i64 { !self } }
// docs:end:not-trait-impls

// docs:start:bitor-trait
trait BitOr {
fn bitor(self, other: Self) -> Self;
Expand Down
30 changes: 28 additions & 2 deletions noir_stdlib/src/uint128.nr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::ops::{Add, Sub, Mul, Div, Rem, BitOr, BitAnd, BitXor, Shl, Shr};
use crate::ops::{Add, Sub, Mul, Div, Rem, Not, BitOr, BitAnd, BitXor, Shl, Shr};
use crate::cmp::{Eq, Ord, Ordering};

global pow64 : Field = 18446744073709551616; //2^64;
Expand Down Expand Up @@ -228,11 +228,20 @@ impl Ord for U128 {
}
}

impl Not for U128 {
fn not(self) -> U128 {
U128 {
lo: (!(self.lo as u64)) as Field,
hi: (!(self.hi as u64)) as Field
}
}
}

impl BitOr for U128 {
fn bitor(self, other: U128) -> U128 {
U128 {
lo: ((self.lo as u64) | (other.lo as u64)) as Field,
hi: ((self.hi as u64) | (other.hi as u64))as Field
hi: ((self.hi as u64) | (other.hi as u64)) as Field
}
}
}
Expand Down Expand Up @@ -284,3 +293,20 @@ impl Shr for U128 {
self / U128::from_integer(y)
}
}

mod test {
use crate::uint128::{U128, pow64};

#[test]
fn test_not() {
let num = U128::from_u64s_le(0, 0);
let not_num = num.not();

let max_u64: Field = pow64 - 1;
assert_eq(not_num.hi, max_u64);
assert_eq(not_num.lo, max_u64);

let not_not_num = not_num.not();
assert_eq(num, not_not_num);
}
}

0 comments on commit 95d4d13

Please sign in to comment.