Skip to content

feat: Add verification tool for jeff programs#66

Closed
kawacukennedy wants to merge 2 commits into
unitaryfoundation:mainfrom
kawacukennedy:feat/verifier-57
Closed

feat: Add verification tool for jeff programs#66
kawacukennedy wants to merge 2 commits into
unitaryfoundation:mainfrom
kawacukennedy:feat/verifier-57

Conversation

@kawacukennedy

Copy link
Copy Markdown

Closes #57.

Adds verification tool at tools/verifier/ that checks all 7 requirements from the issue:

  1. Required module attributes — entrypoint index bounds check
  2. SSA validity — ensures all value references are within the value table
  3. Def-before-use — catches out-of-bounds value IDs in inputs/outputs
  4. Type consistency — validates input/output types match all operations (QubitOp, QubitRegisterOp, IntOp, IntArrayOp, FloatOp, FloatArrayOp, ControlFlowOp)
  5. Int/float operand consistency — same-bitwidth and same-precision checks for binary arithmetic operations
  6. Qubit linearity — tracks qubit/qureg consumption across operations and nested regions
  7. Region isolation — ensures nested regions only reference values from region sources or definitions within the region

Implementation

  • Rust crate at tools/verifier/ using the reader API (jeff::reader)
  • CLI binary with clap for command-line verification
  • 5 modular check passes: attributes, ssa, types, linearity, isolation
  • Recursive handling of nested control-flow regions (For, While, DoWhile, Switch)
  • 9 integration tests: 3 positive (existing example programs) + 6 negative (invalid fixtures)
  • Tested via cargo test -p jeff-verify

CI integration

  • tools/verifier/** added to the Rust change filter so CI triggers on verifier changes
  • Workspace Cargo.toml updated to include tools/verifier

Notes

  • Uses matches! for array type length wildcards (avoids false positives on intArray/FloatArray length mismatches)
  • Valid examples qubits, entangled_qs, and entangled_calls all pass cleanly

Checks all 7 requirements from issue #57:
- Required module attributes (entrypoint bounds)
- SSA validity (values defined before use)
- Type consistency for all operations
- Int/float operand type consistency (bitwidth/precision)
- Qubit linearity (consumed at most once)
- Region isolation (nested regions don't bypass boundaries)

Tests: 9 integration tests (3 positive + 6 negative) covering all checks.
@kawacukennedy

This comment was marked as low quality.

@denialhaag denialhaag left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for also working on the verifier, @kawacukennedy! 🙂

I had an initial look at your implementation, and you can find some feedback below. This is already going in the right direction!

Comment on lines +12 to +27
fn check(&self, module: &Module<'_>) -> Vec<CheckError> {
let mut errors = vec![];

let entry_id = module.entrypoint_id() as usize;
let func_count = module.function_count();
if entry_id >= func_count {
errors.push(CheckError {
check_name: self.name(),
message: format!(
"Entrypoint index {entry_id} is out of bounds: module has {func_count} function(s)."
),
});
}

errors
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably raise an error if entrypoint is not specified (see, e.g., entangled_qs.txt)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this is not tested.

//! - Required module attributes (entrypoint, tool name/version)
//! - SSA validity (all values defined before use)
//! - Type consistency for operations
//! - Qubit linearity (qubits consumed at most once)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Qubits must be used exactly once. Every qubit must be either destructively measured or freed. The respective check should be adapted and tested accordingly.

Comment thread tools/verifier/src/main.rs Outdated
//! Verification tool for jeff programs.
//!
//! Checks a jeff file for common issues including:
//! - Required module attributes (entrypoint, tool name/version)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking, the tool name and version are not required attributes.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checks here look pretty good already, but it would be nice to improve the test coverage beyond the add operations.

…n, test coverage, doc fix

- attributes: Error when entrypoint not specified (entrypoint_id == 0 with functions)
- linearity: Add qubit leak detection (every qubit must be consumed exactly once)
- isolation: Add region isolation test fixture and integration test
- types: Add int_sub_bitwidth and float_mul_mismatch test coverage
- main: Fix doc comment (tool name/version not required)
- All fixtures updated with explicit entrypoint for multi-function modules
@kawacukennedy

This comment was marked as low quality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add verification tool

2 participants