-
Notifications
You must be signed in to change notification settings - Fork 3
Implement std::hint::black_box intrinsic support in KMIR #659
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
c8e11b0
Add integration test for `black_box` usage in `add_one` function
Stevengre cf346f5
Add SMIR JSON generation and testing utilities
Stevengre 2905f3b
Refactor test utilities and enhance SMIR testing
Stevengre d326b8f
Refactor function mapping in KMIR and enhance SMIRInfo
Stevengre 57c7439
Add IntrinsicFunction constructor to MonoItemKind
Stevengre 85a6051
Implement intrinsic function mapping in KMIR
Stevengre 8d22997
Implement K semantics for intrinsic function execution
Stevengre beb8cb6
Extend test suite to include intrinsic function tests
Stevengre 76402fe
Add expected test output for black_box intrinsic
Stevengre f63acc0
Add project configuration and development guidelines
Stevengre ba0328e
Fix code formatting and linting issues
Stevengre 36f7eb6
Add developer documentation for intrinsics and testing
Stevengre c5efc9a
Remove TODO comment for intrinsic function handling in KMIR documenta…
Stevengre 8257e93
Add development workflow guidelines to CLAUDE.md
Stevengre b439d22
Update intrinsic function handling in KMIR
Stevengre 9986ea9
Add intrinsic function representation updates in KMIR tests
Stevengre 6ad3be1
Enhance intrinsic function handling in KMIR
Stevengre 50aefe8
Refactor whitespace in KMIR functions method
Stevengre 26303ce
Add support for accessing single-element aggregates in #traverseProje…
Stevengre 233d07e
use traditional way to manage tests
Stevengre 2d90282
Refactor test structure and remove unused utility functions
Stevengre 0ac6798
Update documentation for single-element aggregate handling in #traver…
Stevengre 5d68dcf
Remove outdated testing guide from documentation
Stevengre d9113b9
Merge branch 'master' into jh/intrinsic-blackbox
Stevengre b462a35
Update integration tests to modify EXEC_DATA parameters
Stevengre 035c631
Remove unnecessary blank line from Makefile to improve readability.
Stevengre a03620b
update-expected-output
Stevengre cf8455b
use the known keys and
Stevengre File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
# CLAUDE.md | ||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
||
## Repository Overview | ||
|
||
MIR Semantics provides a K Framework-based formal semantics for Rust's Stable MIR (Mid-level Intermediate Representation), enabling symbolic execution and formal verification of Rust programs. | ||
|
||
## Essential Commands | ||
|
||
### Build and Setup | ||
```bash | ||
# Initial setup - install stable-mir-json tool for SMIR generation | ||
make stable-mir-json | ||
|
||
# Build K semantics definitions (required after any K file changes) | ||
make build | ||
|
||
# Full build and check | ||
make check build | ||
``` | ||
|
||
### Testing | ||
```bash | ||
# Run all tests | ||
make test | ||
|
||
# Run unit tests only | ||
make test-unit | ||
|
||
# Run integration tests (requires stable-mir-json and build) | ||
make test-integration | ||
|
||
# Run a single test | ||
uv --directory kmir run pytest kmir/src/tests/integration/test_prove.py::test_prove_rs -k "test_name" | ||
|
||
# Generate and parse SMIR for test files | ||
make smir-parse-tests | ||
``` | ||
|
||
### Code Quality | ||
```bash | ||
# Format code | ||
make format | ||
|
||
# Check code quality (linting, type checking, formatting) | ||
make check | ||
|
||
# Individual checks | ||
make check-flake8 | ||
make check-mypy | ||
make check-black | ||
``` | ||
|
||
### Working with KMIR Tool | ||
```bash | ||
# Activate environment for interactive use | ||
source kmir/.venv/bin/activate | ||
|
||
# Or run commands directly | ||
uv --directory kmir run kmir <command> | ||
|
||
# Prove Rust code directly (recommended) | ||
uv --directory kmir run kmir prove-rs path/to/file.rs --verbose | ||
|
||
# Generate SMIR JSON from Rust | ||
./scripts/generate-smir-json.sh file.rs output_dir | ||
|
||
# View proof results | ||
uv --directory kmir run kmir show proof_id --proof-dir ./proof_dir | ||
``` | ||
|
||
## Architecture Overview | ||
|
||
### Directory Structure | ||
- `kmir/` - Python frontend tool and K semantics | ||
- `src/kmir/` - Python implementation | ||
- `kmir.py` - Main KMIR class handling K semantics interaction | ||
- `smir.py` - SMIR JSON parsing and info extraction | ||
- `kdist/mir-semantics/` - K semantics definitions | ||
- `src/tests/` - Test suites | ||
- `integration/data/prove-rs/` - Rust test programs for prove-rs | ||
- `integration/data/exec-smir/` - Rust programs for execution tests | ||
|
||
### Key K Semantics Files | ||
- `kmir.md` - Main execution semantics and control flow | ||
- `mono.md` - Monomorphized item definitions | ||
- `body.md` - Function body and basic block semantics | ||
- `rt/configuration.md` - Runtime configuration cells | ||
- `rt/data.md` - Runtime data structures | ||
- `ty.md` - Type system definitions | ||
|
||
### Python-K Integration | ||
The Python layer (`kmir.py`) bridges between SMIR JSON and K semantics: | ||
1. Parses SMIR JSON via `SMIRInfo` class | ||
2. Transforms to K terms using `_make_function_map`, `_make_type_and_adt_maps` | ||
3. Executes via K framework's `KProve`/`KRun` interfaces | ||
|
||
### Intrinsic Functions | ||
Intrinsic functions (like `black_box`) don't have regular function bodies. They're handled by: | ||
1. Python: `_make_function_map` adds `IntrinsicFunction` entries to function map | ||
2. K: Special rules in `kmir.md` execute intrinsics via `#execIntrinsic` | ||
|
||
## Testing Patterns | ||
|
||
### prove-rs Tests | ||
Tests in `kmir/src/tests/integration/data/prove-rs/` follow this pattern: | ||
- Simple Rust programs with assertions | ||
- File naming: `test-name.rs` (passes), `test-name-fail.rs` (expected to fail) | ||
- Tests run via `kmir prove-rs` command | ||
- Generate SMIR automatically during test execution | ||
|
||
### Adding New Tests | ||
1. Add Rust file to `prove-rs/` directory | ||
2. Use assertions to verify behavior | ||
3. Run with: `uv --directory kmir run kmir prove-rs your-test.rs` | ||
|
||
## Development Workflow | ||
|
||
### Before Starting Any Task | ||
1. Read README and documentation in docs/ directory first | ||
2. Study existing development patterns and conventions | ||
3. Understand the codebase structure before making changes | ||
|
||
### Modifying K Semantics | ||
1. Edit `.md` files in `kmir/src/kmir/kdist/mir-semantics/` | ||
2. Run `make build` to compile changes | ||
3. Test with `make test-integration` | ||
|
||
### Modifying Python Code | ||
1. Edit files in `kmir/src/kmir/` | ||
2. Run `make format && make check` to verify code quality and formatting | ||
3. Test with `make test-unit` | ||
|
||
### Adding Intrinsic Support | ||
1. Update `_make_function_map` in `kmir.py` to recognize intrinsic | ||
2. Add `IntrinsicFunction` constructor in `mono.md` | ||
3. Add execution rules in `kmir.md` under `#execIntrinsic` | ||
4. Add test in `prove-rs/` directory | ||
|
||
## Debugging Tips | ||
|
||
### Viewing Proof Execution | ||
```bash | ||
# Show specific nodes in proof | ||
uv --directory kmir run kmir show proof_id --nodes "1,2,3" --proof-dir ./proof_dir | ||
|
||
# Show transitions between nodes | ||
uv --directory kmir run kmir show proof_id --node-deltas "1:2,2:3" --proof-dir ./proof_dir | ||
|
||
# Show rules applied | ||
uv --directory kmir run kmir show proof_id --rules "1:2" --proof-dir ./proof_dir | ||
|
||
# Full details with static info | ||
uv --directory kmir run kmir show proof_id --full-printer --no-omit-static-info --proof-dir ./proof_dir | ||
``` | ||
|
||
### Common Issues | ||
- `Function not found` errors: Check if function is in `FUNCTIONS_CELL` (may be intrinsic) | ||
- K compilation errors: Rules must be properly formatted, check syntax | ||
- SMIR generation fails: Ensure using correct Rust nightly version (2024-11-29) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# Adding Intrinsics | ||
|
||
## Development Workflow | ||
|
||
### Step 1: Create Test File | ||
Create `tests/rust/intrinsic/your_intrinsic.rs`: | ||
|
||
```rust | ||
fn main() { | ||
let result = your_intrinsic(args); | ||
assert_eq!(result, expected); | ||
} | ||
``` | ||
|
||
### Step 2: Generate SMIR and Verify Intrinsic Detection | ||
```bash | ||
# Generate SMIR JSON | ||
make generate-tests-smir | ||
|
||
# Update expected outputs and verify intrinsic is detected | ||
make test-unit TEST_ARGS="--update-expected-output" | ||
``` | ||
|
||
Check `tests/expected/unit/test_smir/test_function_symbols/your_intrinsic.expected.json` to confirm the intrinsic appears as `IntrinsicSym`. | ||
|
||
### Step 3: Run Initial Integration Test | ||
```bash | ||
# Run test and update expected output (will show stuck at intrinsic call) | ||
make test-integration TEST_ARGS="-k your_intrinsic --update-expected-output" | ||
|
||
# Backup the initial state for comparison | ||
cp tests/expected/integration/test_exec_smir/intrinsic_your_intrinsic.state \ | ||
tests/expected/integration/test_exec_smir/intrinsic_your_intrinsic.state.backup | ||
``` | ||
|
||
### Step 4: Implement K Rule | ||
Edit `kmir/src/kmir/kdist/mir-semantics/kmir.md`: | ||
|
||
```k | ||
rule <k> #execIntrinsic(mirString("your_intrinsic"), ARGS, DEST) => | ||
/* your implementation */ | ||
... </k> | ||
``` | ||
|
||
### Step 5: Rebuild and Test | ||
```bash | ||
# Rebuild K semantics | ||
make build | ||
|
||
# Run test again | ||
make test-integration TEST_ARGS="-k your_intrinsic --update-expected-output" | ||
|
||
# Compare results | ||
diff tests/expected/integration/test_exec_smir/intrinsic_your_intrinsic.state.backup \ | ||
tests/expected/integration/test_exec_smir/intrinsic_your_intrinsic.state | ||
``` | ||
|
||
The diff should show progress past the intrinsic call if implementation is correct. | ||
|
||
### Step 6: Verify Results | ||
Ensure the test completes successfully and the intrinsic behaves as expected. | ||
|
||
## Example: black_box | ||
|
||
Initial state (before rule): | ||
``` | ||
#setUpCalleeData ( IntrinsicFunction ( mirString ( "black_box" ) ) , ...) | ||
``` | ||
|
||
After implementing rule: | ||
``` | ||
Program continues execution with value 11 passed through | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ syntax MonoItemKind ::= monoItemFn(name: Symbol, id: DefId, body: MaybeBody) | |
[ group(mir-enum) | ||
, symbol(MonoItemKind::MonoItemGlobalAsm) | ||
] | ||
| IntrinsicFunction(Symbol) [ symbol(IntrinsicFunction) ] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two comments:
|
||
syntax MonoItem ::= monoItem(symbolName: Symbol, monoItemKind: MonoItemKind) | ||
[symbol(monoItemWrapper), group(mir---symbol-name--mono-item-kind)] | ||
syntax MonoItems ::= List {MonoItem, ""} | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.