Recursion and loops
Noir FV streamlines formal verification by eliminating the need for loop invariants and termination proofs.
Unlike traditional frameworks that rely on techniques like induction, decrease clauses, and invariants to prove correctness for recursive functions and loops, constrained Noir avoids these complexities altogether.
Why?
- No Recursion – Noir does not support recursion, eliminating the need for termination proofs.
- Bounded Loops – All loops in constrained Noir have fixed bounds, meaning they always terminate.
Example: Verifying a Loop
The following Noir function increments sum
in a loop and successfully verifies without needing invariants:
#[requires((0 <= x) & (x <= y)
& (y < 1000000))] // Prevent overflow when adding numbers
fn main(x: u32, y: u32) {
let mut sum = y;
for i in 0..100 {
sum += x;
}
assert(sum >= y);
}
Since sum
is always increasing and x
is non-negative, the assertion sum >= y
holds for all valid inputs. Noir FV can verify this automatically without requiring additional annotations.
Recursion
In Noir FV you can prove statements for recursive functions but this is not beneficial because programs with recursion can not be built by the standard Noir compiler.