This is a simple Rust project demonstrating a basic counter implementation written in a functional style, designed to be amenable to formal verification.
The counter module provides pure, stateless functions for counter operations. All functions are deterministic and side-effect-free, making them ideal candidates for formal verification using tools like HAX (High-Assurance eXecution) or other formal verification frameworks.
src/lib.rs- Contains the counter implementation with pure functionsCargo.toml- Rust project configuration
new_counter()- Creates a new counter initialized to zeroincrement(c)- Increments a counter by onedecrement(c)- Decrements a counter by oneadd(c, n)- Addsnto the countersubtract(c, n)- Subtractsnfrom the counterreset(c)- Resets the counter to zero
Each function includes documented properties that can be formally verified:
new_counter() == 0reset(c) == 0add(c, 0) == csubtract(c, 0) == c
decrement(increment(c)) == c(when no overflow occurs)increment(decrement(c)) == c(when no underflow occurs)
increment(increment(c)) == increment(c) + 1add(c, 1) == increment(c)subtract(c, 1) == decrement(c)add(add(c, n), m) == add(c, n + m)(when no overflow)subtract(subtract(c, n), m) == subtract(c, n + m)(when no underflow)
increment(u32::MAX) == 0(wrapping behavior)decrement(0) == u32::MAX(wrapping behavior)
To run the unit tests:
cargo testThis code is structured to be verified using formal methods:
- Pure Functions: All functions are pure (no side effects, deterministic)
- Type Safety: Uses Rust's type system for basic guarantees
- Documented Properties: Each function includes properties that can be verified
- Simple Operations: Basic arithmetic operations that are easy to reason about
- Correctness: Verify that functions behave as specified
- Invariants: Prove that certain properties always hold
- Safety: Verify no undefined behavior (handled via wrapping arithmetic)
- Equivalence: Prove that different compositions are equivalent
- Prove that
incrementanddecrementare inverse operations (modulo wrapping) - Prove that
add(c, n)is equivalent tonsuccessiveincrementcalls - Prove that
resetalways returns zero regardless of input - Verify wrapping behavior at boundaries
- The implementation uses
wrapping_addandwrapping_subto handle overflow/underflow deterministically - All functions are pure and stateless, making them ideal for formal verification
- The counter type is
u32, but the design can be generalized to other numeric types
Potential additions for more complex verification:
- Bounded counter with overflow checks
- Counter with maximum value constraints
- Stateful counter with history tracking
- Integration with HAX or other formal verification tools